Why am I getting a Double Render in React’s useEffect Hook?

Daniel Pericich
3 min readApr 26, 2024
Photo by Jørgen Håland on Unsplash

Mastering React render calls is one of the most important parts of learning the framework. Understanding the lifecycle of both class and function-based calls can help increase UI stability and decrease unnecessary rerendering of UI elements. With function components, many re-render calls come inside the useEffect hook. If you have troubleshot extra render calls during the development process, you may have run into the unnecessary double useEffect render. Why do you get a double render call in React’s useEffect hook?

What is StrictMode in React?

There are many items that may cause useEffect to run multiple times. A common cause is updating a state variable in the useEffect’s dependency array. Another is updating a parent component’s state, which causes a parent/child re-render effect. A cause you may not expect is a “feature” specific to local development.

Using the npx create-react-app command on your terminal generates a preconfigured React app. It takes care of some unpleasant parts of setting up a React project including configuring Webpack, building out the directory, adding dependency structures, and creating different production scripts.

This configuration gets you developing in a matter of seconds, but there are preset configurations that can cause issues. The one that we will talk about is the StrictMode setting called in your index.js file.

Index.js is our entry point for our JavaScript to our HTML. Here, we can see this out-of-the-box JSX setup:

Figure 1. The default setup of index.js in React project.s

Our main component, <App />, is wrapped in React.StrictMode components. Where do these components show up on our page? Nowhere, StrictMode is a safety check wrapper for our app and does not have any output for the UI.

While the whole App is wrapped in StrictMode, this tag can wrap any individual JSX or HTML code in your React app. This allows you to isolate StrictMode checking to certain parts of your code.

What does this StrictMode wrapper do? It can do a lot including:

  • Identify components with unsafe lifecycle methods
  • Warn about legacy and deprecated API calls and methods
  • Detect unexpected lifecycle methods
  • Ensure reusable state

If you’ve worked with strict mode in TypeScript you should be familiar with extra safety checks. However, TypeScript checks and React StrictMode differ as StrictMode won’t break your app, but will fill up the console with error and warning messages.

A key focus of StrictMode is informing developers how to maintain state and produce reliable and stable code. It forces extra renders on components and runs on effects to help identify missing cleanups.

The React docs state these goals for StrictMode:

We want to prevent this from being the default behavior or all code, but how?

How to Fix the Double Render on useEffect calls in Development

This fix is as easy as removing the StrictMode wrappers from your index.js file. There are no props or configurations for StrictMode wrappers, so the only way to remove these safety checks is to delete the wrapper from your code.

Before removing the wrapper we can expect this console.log for a basic useEffect hook:

Figure 2. Double call of console.log inside useEffect method in StrictMode.

In order to remove extra safety checks across the whole app, we will remove the StrictMode wrapper acting on the root <App /> component. Now, you will not get double calls on your useEffect methods.

A final point on StrictMode is that it is development only. When you build your production project, you do not need to worry about extra effects being run or components re-rendered as StrictMode will not run in production.

--

--

Daniel Pericich

Former Big Beer Engineer turned Full Stack Software Engineer