react
development_behavior
ai_generated
true
Component renders twice in development. useEffect cleanup runs immediately after mount. API called twice on component mount.
ID: react/react-strict-mode-double-render
88%Fix Rate
92%Confidence
200Evidence
2022-03-01First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 18 | active | — | — | — |
Root Cause
React 18 StrictMode intentionally double-invokes render functions, effects, and cleanup in development to help find impure components and missing cleanup. This is expected behavior, not a bug.
genericWorkarounds
-
93% success Add proper cleanup to useEffect so the double invocation is idempotent
useEffect(() => { const controller = new AbortController(); fetchData(controller.signal); return () => controller.abort(); }, []); -
90% success Make the effect idempotent: running it twice should produce the same result as running it once
For subscriptions: clean up in the cleanup function. For DOM mutations: check if already applied. For API calls: use AbortController or deduplicate with a cache (React Query, SWR).
Sources: https://react.dev/reference/react/StrictMode#fixing-bugs-found-by-double-rendering-in-development
Dead Ends
Common approaches that don't work:
-
Remove StrictMode to stop double rendering
70% fail
StrictMode catches real bugs (missing cleanup, impure renders, deprecated APIs). Removing it hides issues that will surface in production as memory leaks or stale state.
-
Use a useRef flag to skip the second render/effect invocation
75% fail
Defeats the purpose of StrictMode's bug detection. The double invocation is telling you that your effect has a side effect that does not clean up properly.
Error Chain
Preceded by:
Frequently confused with: