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:
- If I read this again after one or two weeks
- Or if I get confused in the future
This post should bring me back to full clarity, not just surface-level knowledge.
What React Hooks Actually Are
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.
Hooks are used to:
- Register state with React
- Register side effects
- Connect component logic to React’s internal update system
That’s why:
- Every hook starts with
use(useState,useEffect,useRef, etc.) - React does not treat hooks like normal JavaScript functions
They are tightly coupled with how React renders and updates components.
Hooks and React Fiber – The Missing Mental Model
This was the real turning point for me.
Internally, React maintains a Fiber Tree.
For each component render:
- React stores hooks in a linked list
- The first hook call becomes the first node
- The second hook call becomes the second node
- And so on…
React does not identify hooks by name.
It identifies them by their order.
This single fact explains all the Rules of Hooks.
Overview of React Hooks
React provides many hooks, but practically speaking:
Most commonly used hooks:
useStateuseEffectuseReduceruseContext
Performance / optimization hooks:
useRefuseCallbackuseMemouseTransitionuseDeferredValue
Low-level or advanced hooks:
useSyncExternalStoreuseInsertionEffect
Different hooks, different purposes —
but the same rules apply to all of them.
Rules of Hooks (The Part That Finally Made Sense)
✅ Rule 1: Only call hooks at the top level
This means:
- No hooks inside
if - No hooks inside loops
- No hooks after
return
❌ Hooks should never be conditionally executed.
Example of a tempting but wrong pattern:
if (imdbRating > 8) {
const [isTop, setIsTop] = useState(true);
}
- Why this is dangerous:
- Sometimes the hook runs
- Sometimes it doesn’t
- The hook order breaks
React can no longer match state correctly
✅ Rule 2: Only call hooks from React functions
Hooks are allowed only inside:
- Functional components
- Custom hooks
❌ Not inside normal JavaScript functions.
Why? Because React only tracks hooks during render.
“This Code Works… So Why Is It Still Wrong?”
This confusion bothered me for a long time.
The Derived State Trap
I used to think something like this was okay:
const [isTop, setIsTop] = useState(imdbRating > 8);
Then syncing it with an effect:
useEffect(() => {
setIsTop(imdbRating > 8);
}, [imdbRating]);
Technically:
- No error
- App works
But conceptually:
- This is unnecessary state
- This is bad design
The Correct Way of Thinking: Derive, Don’t Store
Here is the realization that changed my approach:
If:
- A value can be fully derived from props or other state
Then:
- It should not be stored as state
The better approach:
const isTop = imdbRating > 8;
No extra state
No effect
No extra re-render
Cleaner logic and fewer bugs.
Understanding State Updates with Average Rating
Another important concept became clear with this pattern:
setAvgRating(Number(imdbRating));
setAvgRating((avg) => (avg + userRating) / 2);
React supports:
- Direct state updates
- Functional updates
Functional updates should be used when:
- The new state depends on the previous state
This avoids:
- Stale values
- Unexpected behavior due to batching
How I Now Visualize Hooks
This mental model helped me a lot:
- Hooks = nodes in a linked list
- React = the manager of that list
- Changing the order = ❌ system breaks
That’s why:
- Hooks must be called in the same order
- On every render
- Without conditions
Final Realization
The Rules of Hooks are:
- Not arbitrary
- Not React being “strict for no reason”
They are a direct result of React’s internal design.
Once I understood Fiber and hook ordering:
- I didn’t need to memorize the rules
- The rules started making logical sense
Final Thought
If you’re struggling with React Hooks:
- Don’t just learn how to use them
- Learn why they exist
Once the “why” is clear:
- Code becomes cleaner
- Bugs reduce
- Confidence increases
This blog is written for future me as well —
so that this confusion never comes back again.
Top comments (0)