React Keys in Lists
Table of Contents + โ
In the last lesson on React Rendering Lists you turned an array into a list with map. This lesson is about that yellow โkeyโ warning, and why the key keeps your list working when items are added, removed, or reordered.
๐ค Why does React need a key?
When your list changes, React does not rebuild the whole thing. Here is what it does instead.
- React tries to figure out what actually changed, then updates only that part. That is faster than redoing everything.
- Say your list shows three messages and a new one arrives at the top. React needs to know: did all four change? Or did one new message just get added?
- Without help, React cannot tell items apart between one render and the next.
- A key is the help it needs. It is a small label on each item so React can match the old items to the new ones.
- So the key lets React say โthis one is the same as before, this one is new, this one is goneโ and update the screen efficiently.
๐ What is a key?
A key is a unique, stable label you put on each item when you render a list. React uses it to track that item across renders.
- Unique means no two items in the same list share a key.
- Stable means the key stays the same for an item every time, so it does not change on each render.
- The best key is a real id that comes with your data, like
user.idorproduct.id. - So a good key is something that belongs to the item itself and never changes for that item.
Think of it like a phone number. It identifies you and stays the same even when you move house, and React follows an item the same way.
โ ๏ธ The warning when you skip it
If you render a list with map and forget the key, React still shows your list, but it prints a warning in the console.
This is what a list looks like with no key on each item.
function UserList({ users }) { return ( <ul> {users.map((user) => ( <li>{user.name}</li> ))} </ul> );}React renders the names, but you get this in the browser console.
Console warning
Warning: Each child in a list should have a unique "key" prop.So React is telling you it cannot track these items properly yet. Letโs give it the key it is asking for.
โ Use a stable unique id as the key
The fix is to put a key on the outermost element you return from map, and set it to the itemโs own id.
Here we use each userโs id as the key, which is unique and stays the same for that user.
function UserList({ users }) { return ( <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> );}
// users = [// { id: 101, name: "Alex" },// { id: 102, name: "Riya" },// { id: 103, name: "Arjun" },// ]So each <li> now carries a unique id that belongs to that user. React can follow user 102 from one render to the next, even if the order changes. The warning disappears too.
The key goes on the outer element
The key goes on the top-level element you return inside map, the <li> here. Not on something nested inside it. And the key is special, React reads it but does not pass it to your component as a normal prop.
๐ซ Why the array index is a risky key
You might see people use the position number from map as the key. It is the second argument map gives you. It makes the warning go away, but it can cause real bugs.
Here is the risky way next to the safe way, so the difference is clear.
// โ Risky - index changes when the list reorders, inserts, or deletes{users.map((user, index) => ( <li key={index}>{user.name}</li>))}
// โ
Safe - the id belongs to the item and never moves with it{users.map((user) => ( <li key={user.id}>{user.name}</li>))}The trouble is that the index is about the position, not the item, so it lies to React the moment the list changes.
- You delete the first item. Now everyone shifts up, so every index points to a different item than before.
- React thinks item 0 just changed its data, not that item 0 was removed. So it can keep the wrong row on screen.
- The worst case is with inputs. If each row has a text box, the typed text can stay glued to the position and jump to the wrong item after a reorder or delete.
- So index works only for a list that never changes order and never adds or removes items in the middle. If your list moves at all, reach for a real id.
Index keys and form inputs
This bug is sneakiest with checkboxes and text inputs inside list items. Because the index sticks to the position, the input state can attach to the wrong row after a delete or reorder. A stable id key prevents this completely.
๐ The rules for keys
Keys come with a couple of simple rules. Get these right and you will never see the warning again.
- Keys must be unique among siblings, meaning unique inside that one list. Two separate lists can both use
key={1}, that is fine. - The key goes on the outermost element returned by
map, not on a child inside it. - Prefer a real, stable id from your data. Use the index only when the list is fixed and never reorders.
- Do not make a key with
Math.random(). It gives a new value every render, so React thinks every item is brand new and re-renders the whole list each time. - So the short version is: one unique, stable id per item, sitting on the top element of each mapped row.
๐งฉ What Youโve Learned
- โ A key is a unique, stable label on each list item that React uses to tell items apart between renders
- โ React needs keys to know which item changed, was added, or was removed, so it can update efficiently and keep state correct
- โ Without a key, React still renders but warns: each child in a list should have a unique โkeyโ prop
- โ
The best key is a real id from your data, like
user.id, because it is unique and stays the same for that item - โ The array index is risky, it breaks when the list reorders, inserts, or deletes, and can attach inputs to the wrong row
- โ
Keys must be unique among siblings and go on the outermost element returned by
map
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What is a key in a React list?
Why: A key is a unique, stable identifier on each item. React uses it to match old items to new ones across renders so it can update only what changed.
- 2
Which is the best choice for a key when rendering a list of users?
Why: A real, stable id that belongs to the item is the best key. It is unique and stays the same for that item across renders, which is exactly what React needs.
- 3
Why is using the array index as a key risky?
Why: The index describes the position, not the item. When the list changes, indexes shift to different items, so React can keep the wrong row or attach an input's text to the wrong item.
- 4
Where does the key prop go when you return items from map?
Why: The key goes on the top-level element returned inside map, and it must be unique among siblings in that one list. React reads it but does not pass it as a normal prop.
๐ Whatโs Next?
Now you know how to give React a key so it tracks your list items correctly. Next youโll put all of this together and build a list that grows, shrinks, and updates as the user interacts with it.