React Strict Mode Effect Re-running
In development, React Strict Mode can perform an extra effect setup-and-cleanup cycle when a component first mounts. This is designed to reveal effects that do not correctly clean up resources or that rely on unsafe side effects.
Strict Mode is a development-time tool that helps expose bugs in components. For effects, React can simulate an additional setup followed by cleanup before the normal setup proceeds. This behavior does not mean the effect is permanently configured to run twice in production.
An effect should therefore be written so that its setup can safely happen more than once and its cleanup fully reverses what setup created. Typical resources include subscriptions, event listeners, timers, observers, and connections.
For example, an effect that subscribes to an event should return a cleanup function that removes the same subscription. Without that cleanup, development Strict Mode can make the problem visible because multiple subscriptions may accumulate.
Strict Mode is not a reason to suppress the second execution with a ref or global flag. Such workarounds can hide the underlying lifecycle bug and make the component incorrect when it is actually mounted, unmounted, or remounted.
Key points
- The extra effect cycle is development-only Strict Mode behavior.
- React performs setup and cleanup to test whether an effect is resilient to remounting.
- Cleanup should undo subscriptions, timers, listeners, connections, and other external resources.
- Do not use flags merely to prevent an effect from running again; fix missing or incorrect cleanup instead.
- An effect should be safe when its setup and cleanup lifecycle is repeated.
Interview questions
Should you prevent an effect from running twice with a ref?
Usually no. A ref-based guard can hide the symptom while leaving the resource lifecycle incorrect. Components can genuinely be mounted and remounted, so code should tolerate the relevant setup and cleanup lifecycle instead. The preferred fix is to make the effect synchronize correctly and provide complete cleanup.
Why does a useEffect appear to run twice in React Strict Mode?
In development, Strict Mode deliberately exercises an effect's lifecycle more aggressively. React can perform setup, cleanup, and then setup again during the initial mount sequence. This helps reveal effects that leak resources or have incomplete cleanup. The extra cycle should not be treated as evidence that the application will perform the same work twice in production.
How should you write an effect that is safe under Strict Mode effect re-running?
Make setup acquire or establish exactly the resource the component needs, and return cleanup that reverses that operation. For example, if setup adds an event listener, cleanup should remove that same listener using the same function reference. The effect should remain correct if this setup-cleanup sequence is exercised repeatedly. This makes the code robust rather than merely hiding Strict Mode's diagnostic behavior.
What kinds of bugs is Strict Mode effect replay intended to expose?
It can expose missing cleanup, duplicated subscriptions, leaked timers, stale external connections, and other effects that are not resilient to their lifecycle being restarted. The important abstraction is synchronization with an external system rather than treating an effect as a one-time imperative command. If setup cannot safely be followed by cleanup and another setup, the effect often has a lifecycle problem. Strict Mode makes that problem easier to observe during development.