Extracting <Todo />
You already extracted Todo into its own file in step 2 and pass it a todo prop in step 3. This step is about what makes that decomposition worth it — the seams it creates for the next several steps to work cleanly.
Goal
Todo renders the per-item structure that all later features (checkbox, edit input, delete button) will hang off of. TodoList keeps the list-level concerns: the array, eventually the handlers.
React concepts you’ll use
- Single-responsibility components — see Component conventions
- Props as the interface between parent and child
- Destructuring in the parameter list
Implementation
-
Todorenders a<label>wrapping a checkbox input and a span containing the label - The checkbox’s checked state mirrors the todo’s
completedfield - The checkbox is disabled (and read-only) so React doesn’t warn about a controlled input without
onChange - The
<label>and the checkbox are linked via matchingid/htmlFor -
Todoholds no internal state yet — sametodoin, same DOM out
Try it
Expand Todo so each list item shows a checkbox (visible, disabled) followed by the todo’s label. The TodoList itself doesn’t need to change.
Solution
// src/components/Todo.jsx
export default function Todo({ todo }) {
return (
<li>
<label htmlFor={todo.id}>
<input
type="checkbox"
id={todo.id}
checked={todo.completed}
disabled
readOnly
/>
<span>{todo.label}</span>
</label>
</li>
);
}// src/components/TodoList.jsx — unchanged from step 4Why this works
Splitting list-level concerns (the array, eventually the handlers) from item-level concerns (rendering a row, eventually its checkbox/edit/delete events) is what lets each remaining step be one small change. Todo becomes a pure function of its todo prop — same input, same DOM. The disabled + readOnly on the checkbox silences a React warning about controlled inputs without onChange; both drop in step 7 when a real handler arrives.
What you should see now
Each list item is now a checkbox followed by its label. The checkboxes are visible but unclickable. <TodoComposer /> is still a placeholder.
Step 6 wires up the composer so you can add new todos.