Rreact.wiki
React Interview Questions

Explain the rules of Hooks. Why must they be called at the top level and in the same order?

InternalsHard6/21/2026hooksrenderingdependency arraystate consistencyinternals

React relies on consistent call order and position to map Hook invocations to their internal state slots—violating the rules breaks this mapping and causes silent, hard-to-debug bugs.

Short Answer

Hooks must be called at the top level (not inside loops, conditions, or nested functions) and in the same order on every render because React uses an internal linked list of “memory cells” tied to the call order—not names or identifiers—to preserve state and effects across renders.

Details

React maintains a hidden, per-component memory buffer (a linked list of memoizedState nodes) that corresponds 1:1 with each Hook call. On the first render, React creates a new node for each Hook invocation in sequence. On subsequent renders, React walks this list in the same order, assigning each Hook’s return value from its stored node. If you conditionally skip useState() (e.g., inside an if), the call order shifts—the next Hook reads from the wrong node, causing mismatched state, stale closures, or incorrect effect dependencies. The dependency array isn’t directly responsible for the rule—but inconsistent Hook order breaks dependency tracking: useEffect’s cleanup and re-run logic depends on correct state/prop reads, which only happen if prior Hooks (like useState or useRef) resolved correctly.

Example

TSX
function BadComponent({ shouldShow }) {
  if (shouldShow) {
    const [count, setCount] = useState(0); // ✅ called
  }
  const [name, setName] = useState(''); // ❌ skipped when shouldShow is false → order shifts!
  useEffect(() => { /* depends on name */ }, [name]); // May read stale or undefined name
}

Bonus

To stand out: explain how React enforces this at runtime—it’s not just convention. React’s development build includes a call-counter (currentlyRenderingFiber.memoizedState) and throws a precise error (“React Hook … cannot be called inside a callback”) when it detects an out-of-order call. Also mention that custom Hooks inherit these rules transitively: every Hook inside your custom Hook must follow them too—and that eslint-plugin-react-hooks statically analyzes call order using AST traversal, catching violations before runtime.