javascript 63 lines · 8 steps

Preventing re-renders in a React todo list

A memoized row plus stable useCallback handlers keep unchanged todo items from re-rendering on every keystroke.

Explained by highlit
1import { useState, useCallback, memo } from 'react';
2 
3const TodoItem = memo(function TodoItem({ todo, onToggle, onRemove }) {
4 return (
5 <li className={todo.done ? 'done' : ''}>
6 <label>
7 <input
8 type="checkbox"
9 checked={todo.done}
10 onChange={() => onToggle(todo.id)}
11 />
12 {todo.text}
13 </label>
14 <button onClick={() => onRemove(todo.id)}>×</button>
15 </li>
16 );
17});
18 
19export default function TodoList() {
20 const [todos, setTodos] = useState([]);
21 const [draft, setDraft] = useState('');
22 
23 const addTodo = useCallback(() => {
24 const text = draft.trim();
25 if (!text) return;
26 setTodos((prev) => [...prev, { id: crypto.randomUUID(), text, done: false }]);
27 setDraft('');
28 }, [draft]);
29 
30 const toggleTodo = useCallback((id) => {
31 setTodos((prev) =>
32 prev.map((t) => (t.id === id ? { ...t, done: !t.done } : t))
33 );
34 }, []);
35 
36 const removeTodo = useCallback((id) => {
37 setTodos((prev) => prev.filter((t) => t.id !== id));
38 }, []);
39 
40 return (
41 <section>
42 <div className="composer">
43 <input
44 value={draft}
45 onChange={(e) => setDraft(e.target.value)}
46 onKeyDown={(e) => e.key === 'Enter' && addTodo()}
47 placeholder="What needs doing?"
48 />
49 <button onClick={addTodo}>Add</button>
50 </div>
51 <ul>
52 {todos.map((todo) => (
53 <TodoItem
54 key={todo.id}
55 todo={todo}
56 onToggle={toggleTodo}
57 onRemove={removeTodo}
58 />
59 ))}
60 </ul>
61 </section>
62 );
63}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1memo only helps when the props you pass are referentially stable across renders.
  2. 2Wrapping handlers in useCallback with the right dependencies gives child components props that don't change every render.
  3. 3Updating state immutably with map and filter lets React detect exactly which items changed.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Preventing re-renders in a React todo list — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code