Why does my useEffect run twice on mount?
React useEffect runs twice on mount in development when Strict Mode deliberately runs one extra setup-cleanup-setup cycle. It does not happen in production builds, and the fix is to write the cleanup the effect was missing rather than to guard the effect or remove Strict Mode.
Answer
Short answer
React useEffect runs twice on mount in development when the component is inside <StrictMode>. React intentionally performs a setup-cleanup-setup cycle to expose effects that do not clean up subscriptions, timers, listeners, or in-flight requests. It does not happen in production; the interview answer is to make the effect safe to run twice, not to hide the second run with a ref guard.
Was this answer helpful?
Likely follow-ups
- How would you cancel an in-flight fetch in the cleanup function, and what happens to the rejected promise?
- When is an empty dependency array the wrong choice, and how do you tell?
- Why did React 18 introduce this behaviour, and what future feature was it preparing for?
- Which of this work belongs in an effect at all, versus in an event handler or a data-fetching library?
Related questions
- How is `this` determined in JavaScript, and why does a method lose it when you pass it as a callback?mediumAlso on strict-mode4 min
- Angular, Vue and React are answers to the same problems. Compare how each handles change detection, reactivity and dependency injection.hardAlso on react6 min
- A user deletes the second row of an editable list and the wrong row now shows the text they typed. What is going on?mediumAlso on react5 min
- You wrapped the component in React.memo and it still re-renders on every keystroke. Why?mediumAlso on react4 min