Atul Anand Oraon
Posted on May 22, 2024
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
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;
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);
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.
Posted on May 22, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.