easyReact#40

List rendering with keys

Prompt

Render a list of groceries from an array of objects { id, name }. Each item must have a unique key prop taken from the data — not the array index.

Solution

const groceries = [
  { id: 1, name: 'Milk' },
  { id: 2, name: 'Bread' },
  { id: 3, name: 'Eggs' },
]

export default function GroceryList() {
  return (
    <View>
      {groceries.map(item => <Text key={item.id}>{item.name}</Text>)}
    </View>
  )
}
Mentor's take

Keys exist because of how reconciliation matches list children between renders. Without keys, React pairs old and new children by index — insert one item at the top and every row below it diffs against the wrong previous row, so React mutates all of them instead of moving one. key lets children match by identity: same key, same fiber, state and DOM preserved; the reconciler reorders instead of rewriting.

The mechanics are one line: map the data to elements, put key on the outermost element returned from the map (not on some nested child), and source the key from a stable id in the data. Stability is the whole contract — the key must identify the entity, not the position.

Index-as-key is exactly as broken as no key, because the index is the position. It bites hardest when rows hold state: reorder a list of inputs keyed by index and the text stays in the old slots while the labels move. Math.random() as key is worse — a new identity every render means full teardown and remount of every row.

Red flag: Saying "keys silence the console warning." Keys are a correctness mechanism for the diffing algorithm; the warning is just the messenger. Explain identity-vs-index matching or the answer reads as memorized.

Say it: "Keys give list children identity so reconciliation matches by entity instead of index — I key on a stable data id, never the index, because index keys corrupt row state on reorder."