Components and JSX · Lesson 4 of 21
Rendering lists and keys
map and filter inside JSX, why keys matter, and why the index is usually wrong.
To render an array, turn each item into JSX with map. Each item needs a `key` that's unique among its siblings, so React can tell them apart when the list changes.
const courses = [
{ id: 1, title: "HTML & CSS", price: 0 },
{ id: 2, title: "JavaScript", price: 450 },
{ id: 5, title: "React", price: 600 },
{ id: 6, title: "C++", price: 500 },
]
function App() {
const paid = courses.filter((c) => c.price > 0)
return (
<div>
<h3>{paid.length} paid courses</h3>
<ul>
{paid.map((c) => (
<li key={c.id}>{c.title}: {c.price} EGP</li>
))}
</ul>
</div>
)
}Why keys?
Try this: type something into the input next to "Laila", then press the button that adds a student at the top. The left list uses the index as key, so your text jumps to another student. The right uses id, so it stays put.
function Row({ name }) {
return <li>{name} <input placeholder="note" size={8} /></li>
}
function App() {
const [people, setPeople] = useState([{ id: 1, name: "Laila" }, { id: 2, name: "Omar" }])
const addFirst = () => setPeople([{ id: Date.now(), name: "New" }, ...people])
return (
<div>
<button onClick={addFirst}>Add at the top</button>
<div style={{ display: "flex", gap: 24 }}>
<ul><b>key = index</b>{people.map((p, i) => <Row key={i} name={p.name} />)}</ul>
<ul><b>key = id</b>{people.map((p) => <Row key={p.id} name={p.name} />)}</ul>
</div>
</div>
)
}| Before | After adding at the top | key = index |
|---|---|---|
0: Laila | 0: New | React thinks 0 is still the same item and keeps its input |
1: Omar | 1: Laila | and so on |
2: Omar | a new item |
Spot the bug
React logs a warning here. Which line?
Exercise
In a <ul>, list only the students with 200 xp or more, highest first, as Nour (410), each li with a key.
Nour (410) Laila (320) Mariam (275)
const students = [
{ id: 1, name: "Laila", xp: 320 },
{ id: 2, name: "Karim", xp: 150 },
{ id: 4, name: "Nour", xp: 410 },
{ id: 6, name: "Mariam", xp: 275 },
]
function App() {
return <ul></ul>
}Learn more from
Played 0 of 2 games
Sign in to save your progress and earn XP.