DEV Community

Cover image for React Rendering the component Twice
Atul Anand Oraon
Atul Anand Oraon

Posted on

React Rendering the component Twice

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

VITE_Environent="DEV"
# if using vite
REACT_APP_Environent="DEV"
# If using create-react-app
Enter fullscreen mode Exit fullscreen mode

Have a file to store your environment variables like this

env.config.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;
Enter fullscreen mode Exit fullscreen mode

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

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);
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)