Rules of Hooks: Call Order Is Sacred
Hook calls must keep the same order every render because React maps them to state by array index. Only call hooks at the top level of React functions. Break the order and React desyncs, producing stale state or crashes.
Why it exists
Before hooks, React class components stored state on the instance and lifecycle methods were explicit. Functional components were purely stateless. Hooks were invented to give functional components the same powers without rewriting them as classes, but React needed a way to attach persistent state to a function that gets re-invoked every render. Since functions have no stable instance reference that survives re-execution, React needed a mechanism outside the component to remember which piece of state belonged to which call.
The mental model
Imagine a spreadsheet where each row is a hook and the row number is its identity. On every render, React reads down the sheet line by line. If you insert or delete a row in the middle, every row below it shifts and the data in column two gets read as if it were column three. Hooks are not normal utility functions you can call conditionally or inside loops. They are declarations of stateful dependencies that must be registered in the exact same sequence every time so React's internal ledger stays aligned with your component.
How it works
React stores hook state in a linked list attached to the fiber node representing your component. When your component runs, React walks that list in order. The first hook call maps to the first node, the second to the second, and so on. The rules enforce this: only call hooks from React functions, and only at the top level. Calling inside an if block means the hook might execute on render one but skip on render two, so React thinks the next hook is the previous one. The ESLint plugin react-hooks/rules-of-hooks exists precisely to catch these violations at build time before they corrupt runtime state.
When to use it
You are following the rules whenever you write useState, useEffect, or custom hooks at the top scope of a component or custom hook body, before any early return. This applies to every functional component that manages state, performs data fetching, subscribes to events, or holds refs. The rules are not optional conventions; they are structural requirements for React's reconciliation engine.
When not to use it
Do not call hooks inside loops, conditions, or nested functions. Do not call them after an early return in your component. Do not call them from regular JavaScript functions that are not components or custom hooks. If you need conditional logic, move the condition inside the hook or inside the hook's callback, not around the hook call itself.
One canonical example
A common mistake is writing a component that calls useEffect only if a prop exists. A developer writes if userId then useEffect to avoid fetching when userId is null. On the first render userId is present so the effect hook is first in the list. On the next render userId is null so the hook is skipped. React now treats the next hook, perhaps a useState, as if it were the effect hook. The result is a corrupted component state or a crash. The correct pattern is to always call useEffect and check userId inside the effect body, or to return early before any hooks are called.
Interview question
If a component calls useEffect inside an if block followed by useState, and the next render skips that if block, what occurs?
- a.The useState initializer runs again and resets the component state
- b.React throws a runtime error the moment the hook order changes
- c.React ignores the skipped useEffect and leaves the useState mapping unchanged
- d.React treats the useState call as if it were the useEffect hookCorrect
Why? this is the answer
React matches hooks to internal fiber nodes by sequential call order, so skipping the effect causes every subsequent hook to shift up and reuse the wrong state node. It does not throw immediately or reset state cleanly; it desyncs silently, which is exactly why the ESLint rule exists to block this pattern at build time.
Just read this? Test yourself on what you have been reading.
- #react
- #hooks
- #rules-of-hooks
- #javascript
- #frontend
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.
See open roles