Introduction
In this lesson, we will cover keys in React. Keys are special props for our components and we’ll learn why they are used.
Lesson overview
This section contains a general overview of topics that you will learn in this lesson.
- Learn what keys are in React and why it needs them.
- Identify examples of good and bad key usage in React applications.
Why does React need keys?
In the upcoming lessons as you learn more about the internal workings of React, more specifically the re-rendering process, you will understand the importance of keys. For now, we will keep it short.
In the previous lesson on rendering lists, we used the .map()
method to iterate over an array of data and return a list of elements. Now imagine, if any of the items in the list were to change, how would React know which item to update?
If the list were to change, one of two things should happen:
- we completely re-render the entire list, or:
- we hunt down the specific items that were changed and only re-render those.
Assuming we want to hunt down that one specific item that was changed and NOT re-render the entire list, we need something to track that specific item. We can track down a specific item by using a key
.
When the list is updated for whatever reason (either from a server or a user interaction), React matches the keys
of each of the previous list items to the updated list. If there were any changes, React will only update the items that have changed.
As long as keys
remain consistent and unique, React can handle the DOM effectively and efficiently.
Using keys
We will be using props
here, and you will learn more about them in the next lesson. For now, you just need to know that props
are arguments that are passed into components.
Keys are passed into the component or a DOM element as a prop. You should already be familiar with the syntax.
<Component key={keyValue} />
//or
<div key={keyValue} />
Now that we know the syntax, the next question is: what should be used as a key? Ideally, there should be some identifier that is unique to each item in the list. Most databases assign a unique id to each entry, so you shouldn’t have to worry about assigning an id yourself. If you are defining data yourself, it is good practice to assign a unique id
to each item. You can use the crypto.randomUUID() function to generate a unique id. Let’s look at an example:
// a list of todos, each todo object has a task and an id
const todos = [
{ task: "mow the yard", id: crypto.randomUUID() },
{ task: "Work on Odin Projects", id: crypto.randomUUID() },
{ task: "feed the cat", id: crypto.randomUUID() },
];
function TodoList() {
return (
<ul>
{todos.map((todo) => (
// here we are using the already generated id as the key.
<li key={todo.id}>{todo.task}</li>
))}
</ul>
);
}
Additionally, if you’re sure the list will remain unchanged throughout the application’s life, you can use the array index as a key. However, this is not recommended since it can lead to confusing bugs if the list changes when items are deleted, inserted, or rearranged. You will learn more about this in the assignment section’s linked article.
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
function MonthList() {
return (
<ul>
{/* here we are using the index as key */}
{months.map((month, index) => (<li key={index}>{month}</li>))}
</ul>
);
}
Keys are straightforward to use, though there is an anti-pattern you should be aware of. Keys should never be generated on the fly. Using key={Math.random()}
or key={crypto.randomUUID()}
while rendering the list defeats the purpose of the key, as now a new key
will get created for every render of the list. As shown in the above example, key
should be inferred from the data itself.
const todos = [
{ task: "mow the yard", id: crypto.randomUUID() },
{ task: "Work on Odin Projects", id: crypto.randomUUID() },
{ task: "feed the cat", id: crypto.randomUUID() },
];
function TodoList() {
return (
<ul>
{todos.map((todo) => (
// DON'T do the following i.e. generating keys during render
<li key={crypto.randomUUID()}>{todo.task}</li>
))}
</ul>
);
}
Conclusion
Don’t fret if some of the terms covered in the lesson don’t make sense yet. What’s crucial right now is knowing how to use keys effectively in React. As mentioned earlier, the more you learn about React, the more you will understand the importance of keys. Furthermore, using keys is not limited to rendering lists. You might encounter use cases where keys are needed, we’ll leave that for you to discover.
Assignment
-
Read this section on keys in the React docs.
-
Watch this short video demonstrating index as key being an anti-pattern.
Knowledge check
The following questions are an opportunity to reflect on key topics in this lesson. If you can’t answer a question, click on it to review the material, but keep in mind you are not expected to memorize or master this knowledge.
Additional resources
This section contains helpful links to related content. It isn’t required, so consider it supplemental.
- This article on React key attribute by Nadia Makarevich takes an in-depth look into keys.