Study notes · 11% of the exam

Effects, Refs and Synchronization

Effects keep a component in sync with systems outside React. Know when each kind runs, how dependencies are compared, what order setups and cleanups follow, and when you don't need an effect at all.

Key points

  1. 1

    useEffect runs after the commit, usually after paint. useLayoutEffect runs after DOM mutations but before paint, and useInsertionEffect runs before both. Use layout effects only to measure or position without flicker.

  2. 2

    Dependencies are compared with Object.is. No array means every render, [] means mount only, and objects or functions created during render change identity every time.

  3. 3

    Each render has its own props and state. A cleanup sees the values from the render that created it, and a stale closure is what you get when you leave out a dependency.

  4. 4

    Order: setups run child before parent. On an update, all cleanups run before any new setups. On unmount, cleanups run parent before child. Layout cleanups and setups happen synchronously; passive ones come later.

  5. 5

    In development, StrictMode runs setup, then cleanup, then setup again (and double-invokes ref callbacks). Write cleanups that undo setups instead of hiding the second run behind a ref guard.

  6. 6

    Fetching in an effect needs race handling: an ignore flag set in cleanup, or AbortController, whose aborted fetch rejects with AbortError. Framework loaders and data libraries handle this for you.

  7. 7

    useEffectEvent (stable in React 19.2) reads the latest props and state without becoming a dependency. Call it only from effects or the callbacks they start, never during render, and never list it in dependencies.

Common traps

  • Derived data, resets on prop change (use key) and work caused by a click don't belong in effects; they cost extra renders and show stale UI first.

  • setN(n + 1) in an effect with no dependency array loops forever. React logs "Maximum update depth exceeded" but keeps going.

  • Writing ref.current during render is unsafe because renders can be discarded or repeated. Update refs in effects or handlers.

Test yourself on Effects, Refs and Synchronization

Ten questions, with the answer and explanation after each one.