Study notes · 10% of the exam

Advanced and Custom Hooks

Hooks are matched by call order on each component's fiber, custom hooks share logic but never state, and the advanced hooks (useSyncExternalStore, useImperativeHandle, useId, use, useOptimistic) each have sharp rules about identity, timing and where they may be called.

Key points

  1. 1

    Call hooks at the top level and unconditionally; a changed hook count throws, and a changed hook type at the same position silently reads the wrong data.

  2. 2

    use is the one exception: it may be called in conditions and after early returns, but never inside try/catch or event handlers.

  3. 3

    Custom hooks should return stable values: memoise returned objects and functions, or callers' effects re-run on every render.

  4. 4

    useSyncExternalStore needs a module-level subscribe, a cached getSnapshot, and a getServerSnapshot when the page is server-rendered.

  5. 5

    In React 19, ref is a regular prop; useImperativeHandle(ref, create, deps) replaces what the parent receives and follows the same dependency rules as effects.

  6. 6

    useId is for accessibility IDs that match between server and client, never for list keys; separate apps on one page need distinct identifierPrefix values.

  7. 7

    Optimistic state from useOptimistic only lives while an action or transition is pending; outside one, React warns and reverts it.

Common traps

  • usePrevious built from a ref and an effect returns the previous render's value, not the previous different value.

  • A promise created during render and passed to use keeps the component suspended forever.

  • State updates after an await inside startTransition are not transitions unless wrapped in another startTransition.

Test yourself on Advanced and Custom Hooks

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