Why React 18’s Strict Effects Matter and How to Use Them
React 18 extends StrictMode with Strict Effects, causing newly mounted components to run their effects twice in development to surface hidden bugs, while offering guidance on when to enable or disable this behavior for reliable UI state management.
Overview
Strict Mode, supported since React 16.3, marks potential code problems. Adding
<StrictMode>enables special behaviors that run only in development, such as deliberately double‑rendering components to surface unsafe side effects.
With the release of React 18, StrictMode adds support for Strict Effects. In strict mode, React calls a newly mounted component’s effect twice (mount → unmount → mount). Like other strict‑mode behaviors, this runs only in the development environment.
Why React added Strict Effects?
React’s many features face a constraint: components may be mounted and unmounted more than once.
Fast Refresh, enabled by default in Next.js, Create React App, and React Native, re‑executes effects whenever a file is saved. If a component or library occasionally breaks when its effect re‑runs, Fast Refresh cannot be used effectively.
The upcoming Offscreen API relies on the same constraint. It aims to improve UI support for tab containers and virtualized lists and to leverage new browser APIs like
content-visibility. To achieve this, React needs to adjust how effects work.
Consider a conditionally rendered component, such as a current tab. If the component or its children hold state, that state is lost when the component unmounts. Currently, the only way to preserve state is to “lift” it to a higher component or external store like Redux.
The new Offscreen API (and the effect adjustments described here) allow React to keep state by hiding rather than unmounting components. While doing so, React calls the same lifecycle hooks as during unmount, but it also retains the component and DOM element state.
In other words, a component can be “mounted” and “unmounted” multiple times.
When a component is hidden, it is no longer visible in the DOM, just as if it were removed, but it isn’t actually unmounted because we want to keep its state. From the user’s perspective, the effect is the same.
Running imperative code (e.g., positioning tooltips) on an unmounted component makes no sense, and the same applies to hidden components. Therefore, React must inform the component that it has been hidden. It does this by calling the cleanup function (the effect’s cleanup or
componentWillUnmount) once when the component is hidden.
When the component becomes visible again, the process mirrors a mount: React calls the function used during mount (the effect or
componentDidMount) to tell the component to show itself, preserving all previous state.
We have found that this approach works in most production code, though some adjustments are occasionally required.
Translator’s note: React developers in the comments added that they have rolled out Strict Effects on thousands of components with almost no issues. Only in very complex libraries that perform a lot of manual DOM manipulation did they encounter obstacles, which is why they believe this behavior can be added to strict mode without imposing unnecessary burden on developers.
Disabling Strict Effects
If Strict Effects cause serious problems in your application, you can temporarily disable
<StrictMode>until the issue is resolved. There is currently no way to retain the old
<StrictMode>behavior; once enabled, it includes the Strict Effects feature.
KooFE Frontend Team
Follow the latest frontend updates
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.