What are the rules of hooks? Why can't you call a hook inside a condition?
Whether you understand hooks are matched by call ORDER, not by name.
Two rules: call hooks only at the top level (never in conditions, loops, or nested functions), and only from React functions. React tracks hook state by the ORDER of calls on each render — it has no names to go by. If a condition skips a useState on some renders, every subsequent hook shifts by one slot and reads the wrong state. Keeping calls unconditional keeps the order stable. Mechanically, React keeps a linked list (or array) of hook 'cells' per component instance and walks it in the same sequence every render; the Nth useState call always maps to the Nth cell. That's why the fix is always to branch INSIDE the hook, not around it — put the condition in the effect body, or pass a conditional dependency, or early-return AFTER all hooks. The eslint-plugin-react-hooks rules (rules-of-hooks + exhaustive-deps) catch the vast majority of violations at lint time; treat exhaustive-deps warnings as correctness bugs, not style nits. Custom hooks inherit the same rules because they're just functions that call hooks, which is also why they must be named useSomething so the linter can recognize them.
Explaining a 'rendered fewer hooks than expected' error, and why you branch INSIDE a hook, not around it.
// WRONG: conditional hook shifts the order
if (loggedIn) { const [x] = useState(0); }
// RIGHT: hook is unconditional; branch inside
const [x, setX] = useState(0);
if (loggedIn) { /* use x */ }