Key Gotchas
Video Summary
In the previous lesson, I shared my go-to solution for situations where our data doesn't come with a “built-in” ID: when the data is first created, I generate a unique value, and attach it to the data. Then, when I'm iterating through the data, I can use this value as the key.
You might be wondering, though: why am I going through all this trouble when there are simpler solutions available?
For example, I can use the array index as the key:
<button> {stickers.map((sticker, index) => ( <img key={index} /> ))}</button>
Or, maybe I can use an increasing counter, with stickers.length
:
<button onClick={(event) => { const stickerData = getSticker(); const newSticker = { ...stickerData, x: event.clientX, y: event.clientY, id: stickers.length }; }}>
Both of these solutions will work in this case, but they won't work in every case. In other scenarios, these two alternatives will lead to significant performance problems. They can even lead to baffling, hard-to-understand UI bugs.
In this video, we dig into two scenarios where both of these solutions will cause problems. First, we look at a slight variant on the “Sticker” example, where I can right-click to delete stickers:
We also look at an “Invitee List” application:
Unfortunately, it's difficult to adequately summarize the problems with these two scenarios; I highly recommend watching (or re-watching) this video to see exactly what the problems are.
To quickly summarize:
- The problem with using the array index as the key is that we can never delete or re-order the indexes. If we remove the first item in the array, for example, React will actually delete the DOM nodes associated with the last item in the array, and will then have to do a bunch of work on all the other DOM nodes.
- The problem with using
stickers.length
is that it can lead to duplicate keys, if items can be deleted.
Keys are how React uniquely identifies each DOM node. If we tell React that a given DOM node is identified by 0
or 1
, React will change that specific DOM node on every render so that it matches the current UI.
Here are the Figma diagrams from the video:
Here are the two sandboxes from the videos above, with comments explaining some things that were glossed over in the video:
Removable stickers:
Code Playground
Invitee List:
Code Playground