283

My React Component is rendering twice. So, I decided to do a line-by-line debug, and the problem is here:

 if ( workInProgress.mode & StrictMode) { instance.render(); } 

React-dom.development.js

Is it because of the strict mode? Can I disable it? What is Strict Mode? Do I need it?

2
  • 3
    StrictMode should be removed as a last solution. For a more detailed answer see stackoverflow.com/questions/72238175/…. Commented Oct 28, 2022 at 13:00
  • 25
    Here is the answer from the React documentation (source: I wrote it). I wish this was ranked a bit higher. react.dev/learn/… Commented Apr 1, 2023 at 23:02

7 Answers 7

767

StrictMode renders components twice (on dev but not production) in order to detect any problems with your code and warn you about them (which can be quite useful).

If you have StrictMode enabled in your app but don't remember enabling it, it might be because you used create-react-app or similar to create your app initially, which automatically enables StrictMode by default.

For example, you might find that your {app} is wrapped by <React.StrictMode> in your index.js:

 ReactDOM.render( <React.StrictMode> {app} </React.StrictMode>, document.getElementById('root') ); 

If so, you can disable StrictMode by removing the <React.StrictMode> tag:

 ReactDOM.render( {app} document.getElementById('root') ); 
Sign up to request clarification or add additional context in comments.

9 Comments

The docs reference the intentional "double invoking" in Dev mode: "Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions"
Had an event listener invoked twice and was wondering why. Seems the strict mode was the cause. Thx!
For Next.js devs, you can disable it by setting "reactStrictMode: false" in next.config.js file.
StrictMode should be removed as a last solution. For a more detailed answer see stackoverflow.com/questions/72238175/….
Here is the relevant part of React docs: react.dev/learn/…
|
45

Yes you have to remove Strict mode as

Strict mode can't automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions: Class component constructor , render , and shouldComponentUpdate methods.

Source: React Docs: Strict Mode

5 Comments

If I might add, if you keep it on, it will help you write more resilient components by helping you notice bugs earlier. So it's not like you need it, but it's very recommended that you use it. Do note that the double-rendering only happens on development, it doesn't occurs on production.
@Jackyef How do I remove it? or, put my App in Production mode? <React></React> gives an error..
Just remove the <React.StrictMode> that wraps over your app and it will be fine.
you missed out the trailing comma after {app} like this {app},
StrictMode should be removed as a last solution. For a more detailed answer see stackoverflow.com/questions/72238175/….
42

For Next.js user here like my-self, strict mode is also enabled by default and causes this issue.

You can disable it in this way

// next.config.js module.exports = { reactStrictMode: false, } 

2 Comments

You are right, it is by default true, and setting reactStrictMode to false would solve the problem, but also we should keep in mind as nextjs docs recommends, keeping reactStrictMode true, can also be beneficial: nextjs.org/docs/api-reference/next.config.js/react-strict-mode
StrictMode is there for a good reason. Disabling it is the last thing to do. For a more detailed answer, see stackoverflow.com/a/72238236/15288641
19

In a React app with StrictMode:

  • If you are seeing dual console logs like this: Dual console logs image

  • And if you know that StrictMode helps you optimize your app in some way

  • And you don't want to disable StrictMode entirely

Then:

The React Developer Tools Chrome Extension offers an option to Hide logs during second render in Strict Mode. To enable that:

  • Install the extension.
  • In your Chrome Developer Tools window, a new tab called Components is created. Click on it. Components tab image
  • Then click the gear icon inside the components tab. Components gear icon image
  • Then select the Debugging tab, and check the option to Hide logs during second render in Strict Mode. Debugging tab image

You will no more see the dual logs in the console. No dual console logs image

2 Comments

Unfortunately I still see. Also after re-opening the tab.
Does it actually work? I have mutiple console.log calls but this does not work for me...
3

If you are using nextjs and you want to disable strict mode go to your next.config.js file and set reactStrictMode to false

module.exports = { reactStrictMode: false, }; 

but strict mode is recommended for development once you check if the double mount is caused by strict mode it's preferable to enable it

Comments

1

I wouldn't remove strict mode as it was enabled in development environment on purpose - to make the app more robust. I had an API call in the component useEffect and I did not want my API to be called twice - even in development - because each API call costs me money. What I ended up doing was to ignore the first call to the API and keep the second call. It worked only this way - trying to keep the first call and ignore the second call did not work and React did not render the DOM that my component returned. In order to do this I used a global variable to count the fetches count:

let globalFetchedCount = 0; 

Then in my useEffect I increased the count and called my API:

useEffect(() => { globalFetchedCount++; callTheApi(globalFetchedCount); }, []); 

In callTheApi function I checked the value of fetchCount:

const callTheApi= async (fetchCount: Number) => { if (fetchCount === 1 && isDev && isWeb) { console.log('skipping fetch in strict mode fetch count 1'); return; } const response = await doFetch(apiUrl); const data = await response.json(); setMyObject(data.myObject); }; 

You need to define isDev and isWeb - in my case this was a React Native application and the problem was only in the web version launched by hitting "w" in Expo console.

const isDev = __DEV__; const isWeb = Platform.OS === 'web'; 

And lastly my component uses MyObject:

export default function MyComponent() { const [myObject, setMyObject] = useState<MyObject[]>([]); ... useEffect(() => { ... }, []} .... // now use myObject return ( <View> ... </View> ); } 

Comments

0

It seems the component renders twice, but the first rendered component is not unmounted? At least that is the behaviour I'm seeing with React 17, might a bug in my code of course

2 Comments

I think it's your bug. Maybe your state is a nested object. You should destructure it completely
Yeah, I am also facing this issue even with react 18. I am manually deleting one node. Also, sometimes I remove React.StrictMode to confirm if the issue is caused by it or if there is some bug in my code. A bit painful and time-consuming process.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.