useEffect
reactintermediate

useEffect

useEffect handles side effects after render. It replaces componentDidMount, componentDidUpdate, componentWillUnmount. Cleanup prevents memory leaks.

Memory Trick

Think: Render → Commit → useEffect. It runs AFTER the DOM is painted, not during render.

Log in to track your mastery & progress

1️⃣ Definition & Dependency Patterns

useEffect runs after render and handles side effects.

Dependency ArrayWhen it runs
No arrayAfter every render
[]Once, after first render
[a, b]When a or b changes
jsx
useEffect(() => { // side effect return () => { // cleanup (runs before re-run or unmount) }; }, [dependencies]);

2️⃣ Common Patterns

jsx
// 1. Data fetch on mount useEffect(() => { let cancelled = false; fetchData().then(data => { if (!cancelled) setData(data); }); return () => { cancelled = true; }; }, []); // 2. Event listener useEffect(() => { window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // 3. Subscription useEffect(() => { const sub = store.subscribe(handler); return () => sub.unsubscribe(); }, []);

3️⃣ Why does it run twice in dev?

React Strict Mode intentionally runs effects twice in development: mount → cleanup → mount

This detects:

  • Missing cleanup functions
  • Non-idempotent side effects
  • Unsafe legacy patterns

This only happens in development. Production runs effects once.

4️⃣ useEffect vs useLayoutEffect

useEffectuseLayoutEffect
TimingAfter browser paint (async)After DOM mutations, before paint (sync)
Use forData fetching, subscriptionsDOM measurement, preventing flicker
RiskNone for renderingCan block paint if slow

Use useLayoutEffect only when you must read/modify DOM before the user sees it.

Was this helpful?

Test your Knowledge

3 questions to cement what you just learned.