Rendering and data flow
Render a list with map
Turn an array of data into an array of elements or components.
Transform data into elements with map():
function TaskList({ tasks }) {
return (
<ul>
{tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
)
}
React renders each returned element as a sibling. The key helps React match each task with its previous element on the next render. Use a stable id from your data, not the array index, when items can move.
Filter data before mapping when the interface shows a subset:
const openTasks = tasks.filter(task => !task.done)
Keep the transformation pure. Do not delete tasks, update state, or sort the original state array while rendering. Copy before sorting:
const sortedTasks = [...tasks].sort(compareTasks)
Mutating tasks during render breaks React’s snapshot model. The array in state should change only through setTasks in an event handler or Effect.
Render a useful empty state when the array contains nothing. An empty ul often gives no explanation. A short message like “No tasks yet” tells the user what they are looking at.
You can map to components instead of raw elements once the markup grows:
{tasks.map(task => (
<Task key={task.id} task={task} onToggle={onToggle} />
))}
Each row keeps the same data contract: one task object in, one piece of UI out.
When a list item grows, extract a Task component and pass the item plus intent callbacks. Keep the key on the element returned directly from map(). Do not move the key to a wrapper inside Task unless Task itself is the mapped element.
If map() returns nothing useful, check that you used curly braces inside JSX. Without them, JavaScript does not run and the list will not render.
The expression inside { } must evaluate to an array of elements, null, or false. A bare map() call outside braces is ignored by JSX.
Add, remove, and reorder tasks. The displayed order should come entirely from the array used by this render.
Lesson completed