Tools
React Hooks and the Rules of Hooks – The Understanding That Finally Clicked for Me
2026-01-03
0 views
admin
What React Hooks Actually Are ## Hooks and React Fiber – The Missing Mental Model ## Overview of React Hooks ## Most commonly used hooks: ## Performance / optimization hooks: ## Low-level or advanced hooks: ## Rules of Hooks (The Part That Finally Made Sense) ## ✅ Rule 1: Only call hooks at the top level ## ✅ Rule 2: Only call hooks from React functions ## “This Code Works… So Why Is It Still Wrong?” ## The Correct Way of Thinking: Derive, Don’t Store ## Understanding State Updates with Average Rating ## How I Now Visualize Hooks ## Final Realization ## Final Thought Today, something finally clicked for me. I had been using React Hooks for a long time, but if I’m being honest, I didn’t truly understand what they are, why React is so strict about their rules, and why some patterns that seem to work are still considered bad practice. This blog is my attempt to write down what I personally understood, so that: This post should bring me back to full clarity, not just surface-level knowledge. The first misconception that got cleared was this: Hooks are not just normal helper functions. Hooks are special building functions provided by React.
They directly interact with React’s Fiber architecture. They are tightly coupled with how React renders and updates components. This was the real turning point for me. Internally, React maintains a Fiber Tree.
For each component render: React does not identify hooks by name.
It identifies them by their order. This single fact explains all the Rules of Hooks. React provides many hooks, but practically speaking: Different hooks, different purposes —
but the same rules apply to all of them. ❌ Hooks should never be conditionally executed. Example of a tempting but wrong pattern: React can no longer match state correctly Hooks are allowed only inside: ❌ Not inside normal JavaScript functions. Why? Because React only tracks hooks during render. This confusion bothered me for a long time. The Derived State Trap I used to think something like this was okay: Then syncing it with an effect: Here is the realization that changed my approach: No extra state
No effect
No extra re-render Cleaner logic and fewer bugs. Another important concept became clear with this pattern: Functional updates should be used when: This mental model helped me a lot: The Rules of Hooks are: They are a direct result of React’s internal design. Once I understood Fiber and hook ordering: If you’re struggling with React Hooks: Once the “why” is clear: This blog is written for future me as well —
so that this confusion never comes back again. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse COMMAND_BLOCK:
if (imdbRating > 8) { const [isTop, setIsTop] = useState(true);
} Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
if (imdbRating > 8) { const [isTop, setIsTop] = useState(true);
} COMMAND_BLOCK:
if (imdbRating > 8) { const [isTop, setIsTop] = useState(true);
} COMMAND_BLOCK:
const [isTop, setIsTop] = useState(imdbRating > 8); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
const [isTop, setIsTop] = useState(imdbRating > 8); COMMAND_BLOCK:
const [isTop, setIsTop] = useState(imdbRating > 8); COMMAND_BLOCK:
useEffect(() => { setIsTop(imdbRating > 8);
}, [imdbRating]); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
useEffect(() => { setIsTop(imdbRating > 8);
}, [imdbRating]); COMMAND_BLOCK:
useEffect(() => { setIsTop(imdbRating > 8);
}, [imdbRating]); COMMAND_BLOCK:
const isTop = imdbRating > 8; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
const isTop = imdbRating > 8; COMMAND_BLOCK:
const isTop = imdbRating > 8; COMMAND_BLOCK:
setAvgRating(Number(imdbRating));
setAvgRating((avg) => (avg + userRating) / 2); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
setAvgRating(Number(imdbRating));
setAvgRating((avg) => (avg + userRating) / 2); COMMAND_BLOCK:
setAvgRating(Number(imdbRating));
setAvgRating((avg) => (avg + userRating) / 2); - If I read this again after one or two weeks
- Or if I get confused in the future - Register state with React
- Register side effects
- Connect component logic to React’s internal update system - Every hook starts with use
(useState, useEffect, useRef, etc.)
- React does not treat hooks like normal JavaScript functions - React stores hooks in a linked list
- The first hook call becomes the first node
- The second hook call becomes the second node - useCallback
- useTransition
- useDeferredValue - useSyncExternalStore
- useInsertionEffect - No hooks inside if
- No hooks inside loops
- No hooks after return - Why this is dangerous:
- Sometimes the hook runs
- Sometimes it doesn’t
- The hook order breaks - Functional components
- Custom hooks - This is unnecessary state
- This is bad design - A value can be fully derived from props or other state - It should not be stored as state - Direct state updates
- Functional updates - The new state depends on the previous state - Stale values
- Unexpected behavior due to batching - Hooks = nodes in a linked list
- React = the manager of that list
- Changing the order = ❌ system breaks - Hooks must be called in the same order
- On every render
- Without conditions - Not arbitrary
- Not React being “strict for no reason” - I didn’t need to memorize the rules
- The rules started making logical sense - Don’t just learn how to use them
- Learn why they exist - Code becomes cleaner
- Bugs reduce
- Confidence increases
how-totutorialguidedev.toainodejavascript