This is either a bug or intentional behavior. I'm not sure which.
When you render a component wrapped with a <React.StrictMode>
tag, the component's constructor and render functions will get called twice each. While this didn't cause any other noticeable problems, it did send me on a wild goose chase during a debugging session.
Here's a codepen that reproduces the issue using React/ReactDOM 16.4.0:
https://codepen.io/spudly_1470322188/pen/deBqbx?editors=1111
Yep. It鈥檚 intentional and documented here. It only happens in development mode.
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
I just spent half an hour debugging this too :(
The problem is that if strict mode was added long ago, it is not obvious what the source of the double-render is (I was hunting react-router and redux logic).
I think it would be nice if strict mode printed a console statement when used anywhere on the page and currently enabled (i.e. in dev mode), akin to the existing "Download the React DevTools for a better development experience: https://fb.me/react-devtools" advert.
Something like "Strict mode is enabled; some lifecycle methods including constructors and render will be double-invoked to check for side-effects"
Thanks for this issue. I experienced the same issue, it took me long time to debug it. I totally agree with @davidje13 's suggestion.
Yes please. I think there at least needs to be a warning in the console so we can be aware instantly and reminded what's going on.
I'm busy developing a library and put in <React.StrictMode>
into one of my apps that consumes it a while back, and upon going back to it after some time I noticed very strange behaviour with how my library was being used - specifically, way too many renders and listeners being registered (its a state library that registers listeners with a useEffect()
hook, which was now being called twice). So I spent a good amount of time debugging my library when the actual problem was the strict mode wrapper component...
Something else to note, <React.StrictMode>
doesn't seem to be running the cleanup of useEffect()
?
I realized this because my library de-registers its listeners during that cleanup, but they were never being cleaned up. I'm guessing strict mode is actually creating two separate React trees in some way?
In any case, a little more warning would be great here to prevent meaningless debugging - even though we should know better, its sometimes hard to remember everything in your React app that could be causing such an issue.
Most helpful comment
Yep. It鈥檚 intentional and documented here. It only happens in development mode.
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects