Skip to content
react

Why useEffect is running twice in React

Dec 6, 2022Abhishek EH2 Min Read
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:

1npx create-react-app react-use-effect-twice

Update App.js with the following code:

App.js
1import { useEffect } from "react"
2
3function App() {
4 useEffect(() => {
5 console.log("useEffect executed (component mounted)")
6 }, [])
7
8 return <div className="App"></div>
9}
10
11export default App

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:

App.js
1import { useEffect } from "react"
2
3function App() {
4 useEffect(() => {
5 console.log("useEffect executed (component mounted)")
6 return () => {
7 console.log("useEffect cleanup (component unmounted)")
8 }
9 }, [])
10
11 return <div className="App"></div>
12}
13
14export default App

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.

Do follow me on twitter where I post developer insights more often!

© 2024 CodingDeft.Com