React Hook "useState" is called conditionally — Rules of Hooks violation
Quick answer
Hooks must be called in the exact same order on every render — never inside an `if`, a loop, or after an early `return`. React tracks hook state by call order, not by name, so a hook that's sometimes skipped desyncs every hook after it. Move the condition inside the hook instead of around it.
What causes this error
React associates each hook call with a position in a fixed, ordered list for that component instance — it has no other way to know which `useState` call corresponds to which piece of state across renders. Wrapping a hook in a conditional means that order can change between renders, silently corrupting every hook's state after it.
The Fix
// Wrong — hook called only when `isAdmin` is true
function Panel({ isAdmin }) {
if (isAdmin) {
const [notes, setNotes] = useState([]); // Rules of Hooks violation
}
return <div />;
}
// Fix — always call the hook; put the condition inside its logic instead
function Panel({ isAdmin }) {
const [notes, setNotes] = useState(isAdmin ? [] : null);
return <div />;
}Common causes / variations
- An early `return` placed before some of the component's hook calls
- A hook called inside a `.map()` loop instead of once per top-level component
- A hook call nested inside a ternary or `&&` expression in the component body
Related errors
See also: Invalid hook call, Too many re-renders.
Was this fix helpful?
Comments
Loading comments...