we have a very simple app that only includes a useEffect
that has a console.log("first")
inside.
The problem is that I expect the console.log("first")
to be printed only once when it is executed, but I don’t know why the re-rendering happens and it is logged twice. Please guide me, thanks.
export default function App() {
useEffect(() => {
console.log("first");
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
https://codesandbox.io/s/silly-kilby-yn38cj?file=/src/App.tsx
2
Answers
The reason is the strict mode of react, which works only in developer’s mode. Most of the time you can find the
<React.StrictMode />
component at the top level of your app. Simply remove this and there will be no such behavior.This is a new feature in React 18’s Strict Mode, and this behavior is intentional. The main reason for this new feature is to remind the developers to add a cleanup function in their effect handlers. So basically the component is mounted twice, meaning it is mounted, unmounted, and remounted. Although, it is important to know that this behavior is observed in development mode only and this doesn’t occur in production builds.
To verify the behavior in dev mode, add a cleanup function in your effect handler and try logging something. For instance:
Now the order of logs will be as follows:
This way developers can ensure that the components are less prone to errors and proper cleanup is done while unmounting the component.
To understand this better, you can refer to this solid example demonstrated in the docs.
If you want to understand more about cleanups in effect handler, refer to this article.