React Rendering the component Twice
Tags: react, bug, feature
Published: 2024-05-22 21:45:13


Hi Techies

If you are using React, you would definitely be using the `useEffect` hook right?

What if I told you that the React Renders twice and it's a simple bug 🤨️?
Yeah that's right it's a very small bug, but yet underlooked, although it's only on our local system and not on the actual production build.
But wait a minute, even if it is just in the dev mode. we use `vite` or other  
tools to keep the app running and reflect the changes live. Also, most of us have turned on the *auto-save* option as the cherry on top.

This becomes a hectic challenge when we use `useEffect` to make the 
API calls. As some free APIs have a limit of 100 calls a day, so I would recommend turning off the auto-save on your IDE to stay safe.

Now After this small story, what would be a feasible solution you may ask?
I have a very simple yet effective solution for Ya. So great if you are following along. Let's see how to tackle this bully.

First of we would like to have some environment variables. Yeah, this would be beneficial,  you could choose to name it `environment` or `mode`. Here let's go with the `environment`

In your .env.local you can have it like 


```env
VITE_Environent="DEV"
# if using vite
REACT_APP_Environent="DEV"
# If using create-react-app
```


Have a file to store your environment variables like this

env.config.ts
```TS
const RAPIDAPI_KEY: string = import.meta.env.VITE_RAPIDAPI_KEY;
const RAPIDAPI_HOST: string = import.meta.env.VITE_RapidAPI_Host;
const ENVIRONMENT: string = import.meta.env.VITE_Environent;
const ENVS = {
 RAPIDAPI_KEY: RAPIDAPI_KEY,
 RAPIDAPI_HOST: RAPIDAPI_HOST,
 ENVIRONMENT: ENVIRONMENT, 
};

export default ENVS;
```

I am exporting it like so, to avoid the typos as only by console logs you can detect them so better to do it here once and import and use them elsewhere. Also, look at the naming convention and replace the  `VITE_` with `REACT_APP_` for a smooth experience.

Now, here comes the juicy part for which you have been reading this blog 
the proper way to do it.

main.tsx
```JSX
import React, { memo } from "react";
import ReactDOM from "react-dom/client";
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import App from "./App.tsx";
import "./index.css";
import { Provider } from "react-redux";
import { store } from "./state/store.ts";
import ProductsPage from "./pages/ProductsPage.tsx";
import NotFound from "./pages/NotFound.tsx";
import ENVS from "./env.config.ts";
const renderApp =() => (
 <Provider store={store}>
 <Router>
 <Routes>
 <Route path="/" element={<App />}>
 <Route path="products" element={<ProductsPage />} />
 </Route>
 <Route path="*" element={<NotFound />} />
 </Routes>
 </Router>
 </Provider>
)

console.log("ENVS.ENVIRONMENT", ENVS.ENVIRONMENT)
// Conditionally wrap in React.StrictMode based on the environment
// As it is the one causing this issue
// React.StrictMode 
const app =
 ENVS.ENVIRONMENT !== "DEV" ? (
 <React.StrictMode>{renderApp()}</React.StrictMode>
 ) : (
 renderApp()
 );

ReactDOM.createRoot(document.getElementById("root")!).render(app);
```

Here we have just a simple little change. 
We made an arrow function `renderApp` which is a simple `JSX.element`
and conditionally put it inside the `<React.StrictMode>` if the the Environment is not `DEV` . It does the job and we get the best of both worlds. 

Also if you feel at any moment you need the `React.StrictMode` ,  you can 
easily do so by just putting the `renderApp()` in the `React.StrictMode` .

I know this is going to surely help. Keep coding.