MediumHooks & Closures💻 Output Question

Functional update reads latest state — closure does not

💡

Hint

In React, always use the functional form setState(prev => prev + 1) when the new state depends on previous state — especially in event handlers that fire multiple times or async contexts.

What does this output?

// Simulates useState functional update vs direct update
let state = 0;

// Direct update — closes over current value (stale)
const directUpdate = () => {
  const increment = () => { state = state + 1; };
  increment();
  increment();
  increment();
};

// Functional update — always gets latest
let fState = 0;
const functionalUpdate = () => {
  const updates = [s => s + 1, s => s + 1, s => s + 1];
  updates.forEach(fn => { fState = fn(fState); });
};

directUpdate();
console.log(state);

functionalUpdate();
console.log(fState);

Correct Output

3
3

Why this output?

Explanation: Both produce 3 in this synchronous simulation. The difference matters when updates are batched asynchronously: direct updates (setState(count + 1)) all read the same stale count; functional updates (setState(c => c + 1)) always chain correctly.

Key Insight: In React, always use the functional form setState(prev => prev + 1) when the new state depends on previous state — especially in event handlers that fire multiple times or async contexts.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz