RMD023 — Children built from an array need a key
You rendered an array straight into children — a .map(), a filter, an array literal —
and its rows carry no key. That is supported, and it is what every framework asks for
here: give each row a key from your data.
{this.items.map((item) => <Row key={item.id} item={item} />)}
Not the array index. The index is the position, so keying by it changes nothing.
Without a key the rows are matched by position, so inserting or removing anywhere but the end hands every row below it the previous row's state and DOM — a half-typed input, an open menu, a scroll position, all one row off, while the page still looks right.
What is at stake is only the inside of the array. Rows built this way cannot be confused with the siblings around them: every array in JSX becomes its own group with its own key space, so an element toggling in or out beside the array never reaches into it, and the array never reaches out. A missing key costs you which row inside the array is which.
list() is the same thing without the eager build — the descriptor is rebuilt on
a render and the rows are not — and a key is good practice there too.
It does not fire for a single child, which has no sibling to be reordered against, nor when any child carries a key, which means you are managing identity yourself.
Next
- All diagnostics — every code the framework can report.
- Checking your app — the faults proved from the source, before anything runs.