MediumComponent Logic🐛 Debug Challenge

Early return before hooks — violates Rules of Hooks

Buggy Code — Can you spot the issue?

const hooks = [];
let cursor = 0;

function useState(init) {
  const i = cursor++;
  if (hooks[i] === undefined) hooks[i] = init;
  const set = v => { hooks[i] = v; };
  return [hooks[i], set];
}
function resetCursor() { cursor = 0; }

// Bug: early return skips hooks — shifts cursor on next render
function BuggyComponent(userId) {
  if (!userId) return 'no user'; // EARLY RETURN — skips useState below

  const [name, setName] = useState('Alice'); // sometimes slot 0, sometimes never
  return name;
}

// Render 1: userId provided — useState gets slot 0
resetCursor();
const r1 = BuggyComponent(1);

// Render 2: no userId — early return, cursor stays at 0
resetCursor();
const r2 = BuggyComponent(null);

// Render 3: userId again — but slot 0 state is correct
resetCursor();
const r3 = BuggyComponent(1);

console.log(r1);
console.log(r2);
console.log(r3);

Fixed Code

const hooks = [];
let cursor = 0;

function useState(init) {
  const i = cursor++;
  if (hooks[i] === undefined) hooks[i] = init;
  const set = v => { hooks[i] = v; };
  return [hooks[i], set];
}
function resetCursor() { cursor = 0; }

// Fix: hooks ALWAYS called before any conditional return
function FixedComponent(userId) {
  const [name, setName] = useState('Alice'); // ALWAYS called — slot 0

  if (!userId) return 'no user'; // conditional AFTER hooks

  return name;
}

resetCursor();
const r1 = FixedComponent(1);

resetCursor();
const r2 = FixedComponent(null);

resetCursor();
const r3 = FixedComponent(1);

console.log(r1);
console.log(r2);
console.log(r3);

Bug Explained

Bug: Early return before useState is legal in this simulation but violates React's Rules of Hooks. In React, skipping a hook shifts all subsequent hooks to wrong slots, causing mismatched state.

Explanation: useState always runs — cursor is always at 1 after each render. The conditional is AFTER hooks, so slot 0 is always correctly mapped to name.

Key Insight: Rules of Hooks: NEVER call hooks conditionally, after an early return, or in loops. Always call them at the top level. This is why React relies on call order for state tracking.

Practice spotting bugs live →

38 debug challenges with AI hints

🐛 Try Debug Lab