CodePark/ questions / Performance: re-renders & memo
START PRACTICINGPRACTICE
Frontend question · React › Performance: re-renders & memo

The user adds a new todo, then ticks an older item's checkbox. The new todo disappears. Why?

const TodoItem = memo(function TodoItem({ todo, onToggle }) {
  return <input type="checkbox" checked={todo.done} onChange={() => onToggle(todo.id)} />;
}, (prev, next) => prev.todo === next.todo);

// in the parent
const onToggle = (id) =>
  setTodos(todos.map((t) => (t.id === id ? { ...t, done: !t.done } : t)));
The comparison ignores onToggle, so the older item keeps a stale onToggle that still sees the old todos array

A stale onToggle is the cause. The custom comparison only checks todo, so it ignores onToggle. When an older item's todo has not changed, React skips its re-render. Skipping also means the item never receives the new onToggle. It keeps the handler from its last render, and that handler's todos does not include the new todo. Clicking it sets state from the old array, so the new todo disappears.

The batching option is the tempting wrong answer. The two updates happen in separate events, so batching does not drop anything. Fix the bug in two ways:

• Compare every prop the component uses, or keep the default comparison.

• Write the handler with an updater,
setTodos((ts) => ts.map(...)), so it never depends on a stale array.