Comments

Why do I need Keys in React Lists?

React Lists and Keys

React List and Keys

Lists are an important aspect within your app. Every application is bound to make use of lists in some form or the other. You could have a list of tasks like a calendar app, list of pictures like Instagram, list of items to shop in a shopping cart and so on. The use-cases are numerous. Lists within an application can be performance heavy. Imagine an app with a huge list of videos or pictures and you keep getting thousands more, as you scroll. That could take a toll on the app’s performance.

Because performance is an important aspect, when you are using lists you need to make sure they are designed for optimal performance.

Did you know that in React, when you use lists, each list item needs a unique key? Let’s learn more about lists and keys in React, and how to implement it the right way.

Rendering a simple List component

function ListComponent(props) {
  const listItems = myList.map((item) =>
    <li>{item}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const myList = ["apple", "orange", "strawberry", "blueberry", "avocado"];
ReactDOM.render(
  <ListComponent myList={myList} />,
  document.getElementById('root')
);

The code above shows a ListComponent that renders a list of items that are passed to it as props. In the render() method we have invoked the ListComponent and passed to it a list myList as the props. This code will generate the following output:

  • apple
  • orange
  • strawberry
  • avocado

But when you run this code, you will notice that React also throws a warning.

“Warning: Each child in an array or iterator should have a unique ‘key’ prop.%s%s See https://fb.me/react-warning-keys for more information.%s”

Notice here that the warning is about using a unique key. Keys are necessary to improve performance of your React app, and we will see how.

How do you use Keys in Lists?

Keys help React identify which items have changed (added/removed/re-ordered). To give a unique identity to every element inside the array, a key is required.

To better understand this, let’s refactor the code snippet we saw earlier, to now include keys.

function ListComponent(props) {
  const listItems = myList.map((item) =>
    <li key={item.id}>
       {item.value}
     </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const myList = [{id: 'a', value: 'apple'},
                {id: 'b', value: 'orange'}, 
                {id: 'c', value: 'strawberry'},
                {id: 'd', value: 'blueberry'}, 
                {id: 'e', value: 'avocado'}];
ReactDOM.render(
  <ListComponent myList={myList} />,
  document.getElementById('root')
);

In the code snippet above you can notice that I have included a key to each list item. Observe, that I have updated my original list to be a value-id pair. Each item in the array has an id associated with it. Hence, this is the id that is assigned as a key for each item. This is the best approach to assign unique keys for items on a list.

In this method, the key is a unique string that identifies each item.

Can I just use indexes as keys? – Only under some exceptions

You may wonder, why don’t we just use indexes as keys when looping through an array. Although, many developers have done that in their code it is not necessarily ideal. React recommends that you do not use indexes as keys, since it could impact performance negatively and could lead to some unstable component behaviour.

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

In the example above you can see we are looping through the todos and assigning the index of each item as the the key. This is acceptable for some use cases that we will see below.

Reordering a list, or adding and removing items from a list can cause issues with the component state, when indexes are used as keys. If the key is an index, reordering an item changes it. Hence, the component state can get mixed up and may use the old key for a different component instance.

Therefore, avoid this practice, and make sure unique ids are generated to be assigned as key.

There are some situations when assigning the index as a key maybe acceptable.

What are some exceptions where it is safe to use index as key?

  1. If your list is static and will not change.
  2. The list will never be re-ordered.
  3. The list will not be filtered (adding/removing items from the list).
  4. There are no ids for the items in the list.

If all these exceptions qualify, then you can use an index as a key.

Note: Using index as a key can lead to potential unexpected behaviour within the component.

Keys need to be Unique, but only among its siblings

It is useful to keep in mind that although a key for each item needs to be unique, this rule applies only within an array. In other words, each item within an array needs to have a unique key, but it does not have to be globally unique. The same key can be used across several other components and lists that are unrelated.

Keys don’t automatically get passed as a prop to the component

In the example below, you can see that I am explicitly passing the item.id which is the key as another prop (id) to the component. This is because React does not automatically pass they key like a prop. If you wanted to use the key for some computation, you would need to pass it as another prop like we did in this example.

const content = items.map((item) =>
  <MyComponent
    key={item.id}
    id={item.id}
    title={item.title} />
);

In this example the MyComponent can read props.id and prop.title but not props.key.

Conclusion

Let’s recap the highlights from this post.

  1. Lists are performant heavy and need to be used carefully.
  2. Make sure every item in the list has a unique key.
  3. It is prefered to not use indexes as a key unless you know for sure that the list is a static list (no additions/re-ordering/removal to the list).
  4. Never use unstable keys like Math.random() to generate a key.
  5. React will run into performance degradation and unexpected behaviour if unstable keys are used.

If you are looking for a course to learn all about React, I highly recommend Mosh’s course on Mastering React. This will help you gain all the fundamental knowledge to get started with React.

If you liked this post, please share and spread the word around. Check back this space for more interesting posts on React and JavaScript.

Adhithi Ravichandran is a Senior Software Engineer based in Kansas City. She is currently working on building mobile apps using React Native for critical healthcare scenarios. Adhithi is a regular conference speaker at various tech conferences. Adhithi graduated with a Masters degree in Computer Science from the University of Kansas and has been in the tech industry for over 7 years. She has worked on several technologies over the years, and one of her recent favorite is React Native.
Tags: , , ,

4 responses to “Why do I need Keys in React Lists?”

  1. Nida says:

    Hi. Please also do a blog post about how to use web workers with react/typescript.

  2. Nida Munir says:

    Hi. Can you also share a blog post about functional programming in javascript? Thanks

  3. Branislav Petrović says:

    Great article! Short and consice guideline on using the keys in React.

    Thanks

Leave a Reply

Connect with Me
  • Categories
  • Popular Posts