FS logo

Farhaan Shaikh

FS Blogs

HomeBlogsSubscribe

FS Blogs

Notes on building, shipping, and learning in public.

Essays, experiments, and honest lessons from the work behind this blog.

New posts, no noise.

One short email when something new is published.

No spam. Only new posts.

←Back to blogs

Why React Hooks Break?

A deep dive into how React tracks hooks internally using an indexed system—and why breaking hook order causes bugs, crashes, and chaos.

🧩 Introduction

Blog image

Sounds dramatic.

But React isn’t angry.

👉 It’s just extremely strict about order.

⚠️ The Core Rule (Most Important Line)

Blog image

👉 Every render must call hooks in the same sequence

Example:

javascript

function App() {
  const [name, setName] = useState("");
  const [age, setAge] = useState(0);
  useEffect(() => {}, []);
  const theme = useContext(ThemeContext);
}

👉 React internally sees this as:

plain text

Hook 0 → useState (name)
Hook 1 → useState (age)
Hook 2 → useEffect
Hook 3 → useContext

Next render MUST match this exactly.

Otherwise?

👉 💥 Things break.

🧠 What’s Actually Happening Internally

Blog image

Internal structure (simplified):

javascript

hooks = [
  "",        // name
  0,         // age
  effectFn,  // useEffect
  themeVal   // useContext
];

👉 Each component has something called a Fiber node

👉 That Fiber stores this hook list

Key insight:

👉 React does NOT use variable names

👉 It only uses position (index)

⚙️ Index-Based Tracking (The Real System)

Blog image

On every render:

  1. Cursor starts at 0
  2. First hook → index 0
  3. Second hook → index 1
  4. And so on…

👉 React literally asks:

Not:

This is the entire system.

💥 The Biggest Mistake (Where Bugs Come From)

Blog image

Bad code:

javascript

function App({ isLoggedIn }) {
  const [name, setName] = useState("");

  if (isLoggedIn) {
    useEffect(() => {});
  }

  const [age, setAge] = useState(0);
}

What happens?

Render 1 (isLoggedIn = true):

plain text

[0] useState (name)
[1] useEffect
[2] useState (age)

Render 2 (isLoggedIn = false):

plain text

[0] useState (name)
[1] useState (age) ❌

👉 Now React thinks:

  • index 1 = useEffect
  • but actually it’s useState

👉 💥 Mismatch = chaos

🧪 The Bug in Action

Blog image

What breaks:

  • Effects disappear
  • State shifts
  • Wrong values assigned
  • UI behaves randomly

Sometimes you’ll see:

plain text

React has detected a change in the order of Hooks

Worse case:

👉 No error

👉 Silent UI corruption 😬

🧠 Why These Rules Exist (Not Arbitrary)

Blog image

React could have done:

javascript

Map<"name", value>

But instead chose:

javascript

Array[index]

Why?

  • Faster
  • Simpler
  • Less overhead

Tradeoff:

👉 You must maintain order

📏 The Two Rules of Hooks

Blog image

✅ Rule 1

Only call hooks at the top level

❌ Not inside:

  • if statements
  • loops
  • nested functions

✅ Rule 2

Only call hooks from React functions

❌ Not in:

  • regular JS functions
  • event handlers
  • class components

👉 These rules exist to protect the index system

🛡️ ESLint Saves You

Blog image

Plugin:

bash

eslint-plugin-react-hooks

What it catches:

  • Conditional hooks
  • Missing dependencies
  • Wrong usage patterns

👉 This is why you rarely see hook bugs in production

👉 Because ESLint stops you early.

🧠 Final Mental Model

Blog image

Visualize:

plain text

[0] → name
[1] → age
[2] → effect
[3] → context

👉 Every render:

  • React walks this list
  • In order
  • Same positions

Golden truth:

👉 Hooks are NOT magic

👉 They are just array slots

🎯 Final Takeaways

Blog image
  • Hooks depend on order
  • React uses index, not names
  • Conditional hooks break the system
  • Rules exist to maintain stability
  • ESLint protects you

One-line clarity:

👉 Hooks work because their order never changes.

🔥 Mindset Shift

❌ “Hooks are smart”

✅ “Hooks are positional”

🚀 What You Just Learned

You now understand:

  • Why hook rules exist
  • What React does internally
  • Why conditional hooks break things
  • How React maps state correctly
  • Why ESLint is critical

🔜 Next Post Teaser

👉 useEffect Deep Dive

  • When effects actually run
  • Cleanup logic
  • Dependency array truth
  • Why infinite loops happen

If you want next level:

I can help you:

  • Convert this into viral LinkedIn post (your style)
  • Turn this into blog article with diagrams
  • Or go deeper into Fiber + hook linked list internals

Just say 👍

Post details

Published

Apr 17, 2026

Updated

Mar 31, 2026

Read time

5 min read

Tags

ReactTechnicalBest PracticesGuideTutorial

Related posts

SetState feels broken
ReactApr 15, 2026
SetState feels brokenTechnical

SetState feels broken

React handles state updates internally—why setState is asynchronous, how batching works, and why your state sometimes feels “wrong”.

Open article→
Using index as keys
ReactApr 13, 2026
Using index as keysTechnical

Using index as keys

Why using index as key causes subtle bugs, and how to fix it using stable identities.

Open article→
Re-renders are cheap
ReactApr 10, 2026
Re-renders are cheapTutorial

Re-renders are cheap

React avoids expensive DOM operations using diffing and reconciliation—and why most re-renders are not a performance problem.

Open article→