Lists and Keys
A reading list is, well, a list. You will not write <BookCard /> by hand for every book; you have an array, and you want one card per item. JavaScript's map does that. React then asks for one extra thing you must not ignore.
The rule
Map the array; key each item by who it is, not where it is.
Map the array. map turns each piece of data into a piece of JSX, and React renders an array of elements in order:
const books = [
{ id: 'b1', title: 'The Hobbit', author: 'J. R. R. Tolkien' },
{ id: 'b2', title: 'Dune', author: 'Frank Herbert' },
{ id: 'b3', title: 'Emma', author: 'Jane Austen' },
];
function BookList() {
return (
<ul>
{books.map(book => (
<li key={book.id}>{book.title} — {book.author}</li>
))}
</ul>
);
}To show only some items, filter first and then map: books.filter(b => !b.read).map(...).
Key each item by who it is. A key is how React recognises an item from one render to the next. When the list changes, React matches old and new items by key, then keeps, moves, adds or removes elements accordingly — along with any state inside them.
The key rules:
- Unique among siblings. Two lists elsewhere may reuse the same keys.
- Stable. The same item keeps the same key forever. Ids from your data are ideal.
- On the outermost element returned from
map. If you return a fragment, use<Fragment key={book.id}>, since the<>shorthand cannot take a key. - Not a prop.
BookCardcannot readkey; passidseparately if it needs it.
The shortcut
Ask: "If I shuffled the array, would each key still follow its item?" An id does. An array index does not — index 0 is whoever happens to be first.
Before
The Hobbit has key 0, Dune key 1. You type a note into Dune's card.
Index keys are only safe when the list never reorders, inserts or deletes. Math.random() is always wrong: a new key every render means every item is thrown away and rebuilt.
Drills
Answer fast — trust the rule.
Which is the best key for a book in a list that can be sorted?
Where does key go in books.map(b => <BookCard key=... title={b.title} />)?
Inside BookCard, props.key is...
Two different lists on the same page both use keys b1, b2, b3. Is that a problem?
Why is key={Math.random()} harmful?
Remember
- Map the array; key each item by who it is, not where it is.
- Shuffle test: would each key still follow its item?
- Trap: index keys on lists that change, and random keys ever.
