When first learning React, it's easy to get tripped up by simple mistakes. Even seasoned developers make mistakes.
One area that is oftentimes misunderstood is how to use a
key when iterating over items to be displayed in the UI.
In this article we'll look at three mistakes with React keys and how to avoid them.
First off, let's make sure we understand why we use keys.
The React docs explain that "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."
So, keys help identify elements, especially when React is performing its diffing algorithm to note what has changed in the UI.
With that basic understanding in mind, let's look at our first mistake.
If you are iterating over an array of items, perhaps with the
Array.map helper method, and then displaying those items in the UI, you must add a key to each item.
For example, this shopping list component iterates over an array of grocery items:
But, we forgot to add a key on our
The simple fix is to add that key on the
<li> element on line 9, like this:
Even when using keys, sometimes developers will misunderstand where the key should go. For example, what if we broke out our shopping list into two separate components: the list itself and the list items.
You might think to do something like this:
As you can see, the key is being added on the
<li> element in the
ShoppingListItem component on line 3.
However, the correct place to add the key is the place in which the mapping or iteration is happening. So adding the key down on line 11 would be more appropriate:
Now that we know we need to add a key and where to add it, it's time to tackle the most critical part: what the key should be.
Ideally, the key should be a unique identifier that does not change. If you are iterating over an array of objects retrieved from the backend, each object likely has an
id property you could use. In the case of our shopping list above, each shopping list item name was unique, so the name itself worked well.
If you don't have a unique identifier in the data itself, it is sometimes acceptable to use the index as the key. For example, this list of students having non-unique names:
Tyler is such a great name that we have two Tylers in the list of classmates. Without having a unique ID, using an index as the key is an acceptable solution.
But! Here's the catch: If our data is dynamic in any way, we need to be careful. For example, if our list could be sorted or filtered, we'd run into some problems here when using an index as the key.
Let's now imagine that our list of classmates is used for taking attendance in class. Each student's name will have a checkbox next to it, and, for the teacher's convenience, the list can be sorted alphabetically (A-Z) or reverse alphabetically (Z-A).
The code looks like this:
Now, let's see what happens when we try checking a few of the checkboxes and then sorting our list.
Oh no! The checked checkboxes don't move with the student names correctly! First Adam and John are present, but then after the list is sorted Z-A, only the two Tylers are present!
Because we used an index as our key, the first two items in the list stayed checked, even though the actual item data and text content had changed.
To fix this, we need to use a stable identifier as our key. I'm going to modify our data so that each student has a unique ID that we can use.
Our code now looks like this:
Note that our array of strings is now an array of objects, with each student having a name and an ID. The ID is used as the key on line 37.
Here's the resulting user experience:
Neat! Now the checkboxes move with their accompanying student names when the list is sorted. Adam and John are marked present no matter how the list is sorted.
There you have it. Three mistakes with React keys and three ways to use them correctly. Happy coding!