What Are the Rules of Hooks and Why Do They Exist?
Learn the Rules of Hooks, why call order matters for React state tracking, and what breaks with conditional hook calls.
Expected Interview Answer
The Rules of Hooks state that hooks must only be called at the top level of a React function component or custom hook, never inside loops, conditions, or nested functions, because React tracks hook state by call order across renders, not by name.
React does not know which useState or useEffect call corresponds to which piece of state by reading variable names; instead it relies on the fixed sequence in which hooks are invoked during every render, matching each call’s position in that sequence to a slot in an internal linked list attached to the component’s fiber. If a hook call is skipped on one render because it sat inside an if-statement or a loop that ran a different number of times, every hook call after it shifts by one position, and React silently attaches the wrong stored state or effect to the wrong slot, producing corrupted state or effects firing with stale closures. The second rule, that hooks can only be called from React function components or other custom hooks, keeps that call-order tracking scoped to the render lifecycle React actually manages, rather than from arbitrary regular JavaScript functions where no such tracking exists. ESLint’s eslint-plugin-react-hooks statically enforces both rules, catching violations at build time rather than letting them surface as confusing runtime bugs.
- Guarantees stable, predictable call order so React maps state to the correct slot every render
- Prevents corrupted state and stale closures caused by conditional or looped hook calls
- Keeps hook usage scoped to components and custom hooks React actually manages
- Enables static lint enforcement (eslint-plugin-react-hooks) instead of silent runtime bugs
AI Mentor Explanation
A scorer fills in the same numbered columns on the scorecard in the exact same order every over — column one is always the bowler, column two is always runs conceded — regardless of what actually happened that over. If she suddenly skipped column two on overs where no runs were scored, every later column would shift left and the wicket count would land in the extras box. Hooks work the same way: React fills numbered slots in a fixed order every render, so skipping a hook call under a condition shifts every subsequent slot and corrupts the data. Keeping every hook unconditional at the top level is what keeps the scorecard columns aligned every single over.
Step-by-Step Explanation
Step 1
React renders the component
On each render, React walks the function body top to bottom, encountering hook calls in sequence.
Step 2
Each call maps to a fixed slot
React assigns every hook call a position in an internal per-fiber list, matched purely by call order, not by name.
Step 3
State/effects are read from that slot
On the next render, the hook at position N reads/writes the same slot N, assuming the same number and order of calls.
Step 4
Conditional calls break the mapping
Skipping a hook inside an if/loop shifts every subsequent slot, so lint rules and top-level-only placement prevent this entirely.
What Interviewer Expects
- Explanation of why call order, not naming, is how React tracks hook state
- Concrete description of what breaks when a hook is called conditionally
- Mention of the two rules: top-level only, and components/custom hooks only
- Awareness that eslint-plugin-react-hooks enforces this statically
Common Mistakes
- Saying hooks “just cannot be in an if-statement” without explaining the call-order mechanism
- Confusing the Rules of Hooks with general React best practices
- Forgetting the second rule about only calling hooks from components/custom hooks
- Not mentioning that conditional logic can go inside a hook, just not around the hook call itself
Best Answer (HR Friendly)
“React keeps track of each piece of hook state by the order the hooks are called in, not by variable name, so if I put a hook inside an if-statement and it sometimes runs and sometimes does not, all the hooks after it get mismatched with the wrong stored values. That is why the rule is to always call hooks at the top level of a component, in the same order every time, and I rely on the ESLint plugin to catch violations automatically.”
Code Example
function Profile({ userId, showBio }) {
const [user, setUser] = useState(null) // slot 0
if (showBio) {
// BAD: only called sometimes -- shifts every slot after it
const [bio, setBio] = useState('')
}
useEffect(() => {
fetchUser(userId).then(setUser)
}, [userId]) // this slot’s index now depends on showBio
return null
}
// Correct: hooks always called, condition moves inside
function ProfileFixed({ userId, showBio }) {
const [user, setUser] = useState(null)
const [bio, setBio] = useState('')
useEffect(() => {
fetchUser(userId).then(setUser)
if (showBio) fetchBio(userId).then(setBio)
}, [userId, showBio])
return null
}Follow-up Questions
- What does eslint-plugin-react-hooks catch that code review might miss?
- Why can custom hooks call other hooks but regular functions cannot?
- How does the useState call-order mechanism relate to how class component this.state worked differently?
- What happens internally if two renders of the same component call a different number of hooks?
MCQ Practice
1. Why must hooks be called in the same order on every render?
React uses a per-fiber list indexed by call order to associate state and effects with each hook call.
2. Where can hooks legally be called from?
The second Rule of Hooks restricts calls to components and custom hooks so React can track them via the render lifecycle.
3. What tool statically enforces the Rules of Hooks during development?
eslint-plugin-react-hooks lints for conditional/looped hook calls and calls outside components or custom hooks.
Flash Cards
How does React track which state belongs to which hook? — By fixed call order per render, stored in a per-fiber internal list — not by variable name.
What breaks if a hook is called inside an if-statement? — Every hook called after it shifts slot position, corrupting state and effects.
Where can hooks be called from? — Only the top level of React function components or other custom hooks.
What enforces the Rules of Hooks automatically? — eslint-plugin-react-hooks, catching violations at lint/build time.