The Reducer That Bit the Hand — JavaScript Bug Hunt

Inspired by the debugging sessions behind every "my component won't re-render" question: the reducer mutates the existing state and returns the same object.

  • Language: JavaScript
  • Layer: Frontend
  • Difficulty: Medium
  • Concepts: Immutability, State
  • Modelled on: Redux lore
  • Visible tests: adding returns a new state reference; the previous state is untouched
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the debugging sessions behind every "my component won't re-render" question: the reducer mutates the existing state and returns the same object. Reference equality says nothing changed; memoised components agree; the UI freezes in time.

todosReducer.js must return new objects, never touch the old ones.

Bug report

BUG-MUTATE · Reported by: web platform

reduce(state, action) for ADD_TODO:

  • returns a NEW state object with a NEW items array
  • the previous state object must remain EXACTLY as it was

Observed: state is mutated in place and returned as-is — memo checks see the same reference and skip the re-render.

Logs

[devtools] prevState === nextState -> render skipped (items differ!)

The code as shipped

src/store/todosReducer.js (editable)

// Todos reducer.
exports.reduce = function (state, action) {
  if (action.type === "ADD_TODO") {
    state.items.push(action.text);
    return state;
  }
  return state;
};

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.