DEV Community

Cover image for Why useEffect is running twice in React
collegewap
collegewap

Posted on • Originally published at codingdeft.com

Why useEffect is running twice in React

If you have created a new project recently using Create React App
or upgraded to React version 18, you will see that the useEffect hook gets executed twice in development mode.

If you are new to useEffect hook, you can read one of my previous articles: a complete guide to useEffect hook.

Replicating the issue

Create a new react app using the following command:

npx create-react-app react-use-effect-twice
Enter fullscreen mode Exit fullscreen mode

Update App.js with the following code:

import { useEffect } from "react"

function App() {
  useEffect(() => {
    console.log("useEffect executed (component mounted)")
  }, [])

  return <div className="App"></div>
}

export default App
Enter fullscreen mode Exit fullscreen mode

Here we have a useEffect hook and we are logging a message inside it.

If you run the application and open the browser console, you will see the message is being displayed twice.

two messages in console

Understanding the issue

In StrictMode, starting from React 18, in development mode, the effects will be mounted, unmounted, and mounted again.

This happens only in development mode, not in production mode.

This was added to help React in the future to introduce a feature where it can add or remove a section of the UI while preserving the state. For example, while switching between tabs, preserving the state of the previous tab helps in preventing unnecessary execution of effects like API calls.

We can confirm the behavior by adding a cleanup function to the useEffect hook:

import { useEffect } from "react"

function App() {
  useEffect(() => {
    console.log("useEffect executed (component mounted)")
    return () => {
      console.log("useEffect cleanup (component unmounted)")
    }
  }, [])

  return <div className="App"></div>
}

export default App
Enter fullscreen mode Exit fullscreen mode

If you run the application, you will see the following messages in the browser console:

unmount message in console

Fixing the issue

If you have read the previous section, this is not really an issue. Hence it doesn't need any fixing.

If you still want to avoid useEffect being called twice, you can remove the <StickMode> tag from the index.js file.

Top comments (0)