Why does StrictMode double-invoke effects in dev? What bugs does it expose?

LowIntermediateReact
Preparing for interviews?

Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.

Quick Answer

Explain why React StrictMode intentionally double-invokes certain lifecycles and effects in development, how this simulates mount–unmount–remount, and what kinds of side-effect and cleanup bugs it is designed to reveal.

Answer

Short answer

React StrictMode double-invokes effects in development to stress-test your side effects. It intentionally simulates mount → unmount → mount to expose bugs where effects are not idempotent or don’t clean up properly.

Important: this only happens in development

StrictMode checks run only in dev. Production builds do not double-invoke effects. This is a diagnostic tool, not a performance feature.

The mental model

React is preparing for a future where it can pause, discard, and restart renders (concurrent rendering). To make sure your code is safe for that world, StrictMode asks a brutal question:

"If I mount this component, tear it down, and mount it again immediately… does anything break?"

JSX
function Example() {
  useEffect(() => {
    console.log('effect run');
    return () => {
      console.log('cleanup');
    };
  }, []);

  return <div>Hello</div>;
}

// In StrictMode (dev), you'll see:
// effect run
// cleanup
// effect run
                  

What exactly gets double-invoked?

In React 18 StrictMode (dev):
• Component render functions
• useEffect / useLayoutEffect setup + cleanup
• Certain initializers

React mounts, cleans up, and mounts again immediately.

What React is testing

Bad pattern

Bug it exposes

Missing cleanup

Subscribing but never unsubscribing

Memory leaks, duplicate listeners

Non-idempotent side effects

Sending analytics / POST request on mount

Duplicate network calls or double charges

Mutating external state

Pushing into global arrays, singletons

Duplicated or corrupted global state

Assuming effects run only once

“This runs once on mount” logic

Breaks under remounts / transitions

The kinds of bugs StrictMode is hunting

Classic bug example: missing cleanup

JSX
useEffect(() => {
  window.addEventListener('resize', onResize);
  // ❌ No cleanup
}, []);

// In StrictMode dev, this registers the listener twice 😬
                  

Correct version:

JSX
useEffect(() => {
  window.addEventListener('resize', onResize);
  return () => {
    window.removeEventListener('resize', onResize);
  };
}, []);

// ✅ Safe under mount → unmount → mount
                  

Another classic: non-idempotent side effects

JSX
useEffect(() => {
  analytics.track('page_view'); // ❌ will fire twice in dev StrictMode
}, []);
                  

Better patterns:

• Move it to a router-level boundary
• Or make it idempotent
• Or dedupe on the analytics side

Why React does this (the real reason)

Concurrent React may mount, pause, throw away, and restart trees. If your effects are not resilient to being started and stopped multiple times, you’ll get production-only bugs. StrictMode forces you to see them early.

What this is NOT

• Not a bug
• Not React being slow
• Not something to “work around”

It’s a correctness check.

Rule of thumb

Write effects as if React can run them, clean them up, and run them again at any time. If that is safe, your code is future-proof.

Interview framing

Say it like this:
"StrictMode double-invokes effects in dev to simulate mount–unmount–remount and catch unsafe side effects. It exposes missing cleanups, non-idempotent logic, and code that assumes effects run only once. This is to prepare apps for concurrent rendering and only runs in development."

Summary

StrictMode intentionally double-invokes effects in development to detect unsafe side effects and missing cleanup. It helps catch memory leaks, duplicated subscriptions, non-idempotent logic, and code that assumes a single mount. This behavior is dev-only and exists to make apps safe for concurrent rendering.

Similar questions
Guides
41 / 41