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

Also available as: JSON · Markdown
88%Fix Rate
92%Confidence
200Evidence
2022-03-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
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.

generic

Workarounds

  1. 93% success Add proper cleanup to useEffect so the double invocation is idempotent
    useEffect(() => { const controller = new AbortController(); fetchData(controller.signal); return () => controller.abort(); }, []);

    Sources: https://react.dev/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development

  2. 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:

  1. 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.

  2. 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

Leads to:
Preceded by:
Frequently confused with: