If youâve written some React code, youâve most probably seen this warning:

Almost every React application displays an array list of some kind using the method map. And React tells us that for each element of that list that we return for rendering, we must provide a unique key prop.
But do you know why itâs necessary?
Why does React need this key prop? đ
The official documentation clarifies this perfectly:
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.
When the state of your component changes, the render function will return a new tree of React elements, different to the previous/current one. React needs to figure out what are the differences to efficiently update the UI with the most recent changes. This process of matching both element trees is called reconciliation.
You can read more about Reactâs diffing algorithm here, but the important thing for us are the lists.
So⊠Whatâs exactly the problem with lists?
Well, imagine that you render a list and you donât provide keys for its elements:
<li>Item 1</li>
<li>Item 2</li>
Then imagine a new Item 3 is added. The new tree looks like this:
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
React now needs to compare these two trees to identify the changes made. And to do that, React iterates over both lists of children at the same time and generates a mutation whenever thereâs a difference.
So it will match the first two elements, and generate a mutation for the third one. Good. So far, no problems đ
Now, imagine that a new item is added, but at the beginning. This is the new tree now:
<li>Item 0</li> // <= New item
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
Once again, React will iterate, compare and generate mutations where needed.
When comparing the first element of the old tree (Item 1) with the first element of the new tree (Item 0), they are different, so a mutation is generated.
When comparing the second element of the old tree (Item 2) with the second element of the new tree (Item 1), they are different, so a mutation is generated.
And so on⊠Do you see the problem? React will mutate every child instead of realizing it can keep items 1, 2 and 3 intact. This inefficiency is a problem đ
Key prop to the rescue!
This is why the key prop is needed, to solve this issue. When children have keys, React uses the key to match children in the old tree with children in the new tree.
<li key={0}>Item 0</li> // <= New item
<li key={1}>Item 1</li>
<li key={2}>Item 2</li>
<li key={3}>Item 3</li>
Now React knows right away that the new item is <li>Item 0</li>and the other items have just moved. đ
Ok, got it. But will my app break if I donât use keys? đ€
It depends. Apart from the warning, your application wonât throw an error, but you may produce bugs if you donât provide keys. If you change the order of the list items (either by sorting the list or removing an item, for example), weird things will happen. Youâll see it in the following example.
Letâs code to make it clearer
Iâve coded a very simple app where you are presented with a list of emojis and you can rate each of them.
If the app was just that, the absence of keys wouldnât produce any bug. The list is static and thereâs no way the items are reordered.
But to illustrate the problem, Iâve also added the possibility to remove the emojis from the list.
You can play with it here:
If you check the console, youâll see that React is warning us about not having the key property for our list items.
To see what happens when we donât provide a key, do the following:
- Rate only the đ emoji as âVery goodâ
- Delete the đ emoji
Do you see the problem now? In case you donât want to play with the sandbox (or it doesnât work), here is what happens:

After the deletion, the đ€Ș emoji appears rated as âVery goodâ, which is wrong because we havenât changed its rating at all đŠ
Using index as key
Youâll see that for some simple applications, usually used to teach or explain React concepts, people will use the index as key.
Do you think this solves the problem? đ€
Spoiler alert: it doesnât. You can go ahead and try it, but the same bug will be produced.
As component instances are updated and reused based on their key, if the key is an index, moving an item changes it. As a result, the component will be updated in unexpected ways.
So what to do then?
You need to use some unique value as a key. In this case, Iâve included an id field to make it easier. It doesnât have to be a number, you can use a string if you want. In this case we could even use the emoji itself as key, because each one of them appears only once in the array, but be careful about that.
However, donât overthink it, because the data youâll get in a real life application will most likely have a unique id field to identify each element.
If we rewrite our list item element to be like this:
<li className="emoji-item" key={emoji.id}>
Then both the warning in the console and the problem we had at runtime will be gone đ

So⊠What do you think? đ
Was this useful? I hope it was, and please forgive me (and let me know đ) if there is any error in the code.
Thanks for reading â€ïž
Top comments (15)
Nice article, good to see the unwanted side effect in act đ
Bell articolo, utile vedere i side effetti indesiderati senza key.
Thank you! I'm glad it was helpful!
Good explanation to an important concept
Thank you, I'm glad it helped!
That's an excellent explanation. Bring more
Thank you very much!
Excellent explanation, thank you so much đđ»
Thanks to you for your comment!
Thanks. Excellent answer with clear description!
Thank you, I'm glad it helped!
Good explanation to a important concept !!
Very helpful. You saved my day. ;)
In the emoji example why it deletes last one in the List.It has to be random. Isn't it?
The best explanation so far!
Thank you very much!