šŸŽ Checkout my Learn React by Making a Game course and get 1 month Free on Skillshare!

What to use as keys in React instead of the index

We have seen in a previous post why using indexes as keys when rendering lists in React is not a good idea, and how it can lead to bugs.

Therefore the question: so then what should I put in the key prop if not the index?

As I could not find a simple answer for this one, I went and did some research and this is what I found.

What to use as keys in React instead of index?

Below are some options for setting the key value in React, while looping through a map(data, index) function:

  1. use the id field of the data. In most cases, we get data from an API request and we want to show that data in a list. Most likely the data that comes from the API is from a database, so it has an id field or something similar. We can use this field as the value for the key property:

    // fetch the items from an API  
    {items.map(item => (
    <li key={item.id}>
        {item.description}
    </li>
    ))}

    This is maybe the most straightforward option.

  2. use the randomUUID() method from the Web Crypto API. The window.crypto interface is now available in all major browsers, so we can use it as a built way to generate React keys:

    {items.map(item => (
    <li key={window.crypto.randomUUID()}>
        {item.description}
    </li>
    ))}

    Special kudos to Paul for telling me about this option.

  3. generate the key with an external library. One other way is to use a 3rd party library such as uuid or something similar:

    npm install uuid --save

    And, now we can do:

    import { v4 as uuidv4 } from 'uuid'
    {items.map(item => (
    <li key={uuidv4()}>
        {item.description}
    </li>
    ))}

    A potential downside of this approach is that we may need to install extra libraries to our project.

  4. a mix of index and one unique property. If the data doesn't have a unique identifier, and can't generate one, we can combine the index from the map() with some unique property of the data:

    {items.map((item, index) => (
        <li key={`${index}-${item.someUniqueProperty}`}>
        {item.description}
    </li>
    ))}

The overall idea here is to decouple the index value from the key.

Do not use the useId() hook to generate keys

React 18 introduced the useId() hook. It can seem like a perfect candidate for the key property:

// ā›”ļø don't use the useId hook for keys
import { useId } from 'react'

{items.map((item, index) => (
        <li key={useId()}>
        {item.description}
    </li>
))}

But, please note that useId() hook was introduced for accessibility attributes and was not intended for keys. This is from the official documentation:
What to use as keys in React instead of the index

Is it ever safe to use the indexes as keys in React?

Yes, there are some cases when we can use the index as key. For example when we won't do any manipulation of items. When we will not add, remove, or do something like letting users rearrange the order of the items.

However, using the index as part of the key should be the last resort, as it may lead to issues when the order of items changes or items are added or removed.

In conclusion, when setting keys in React, choose a unique identifier that remains consistent across renders. Prioritize unique identifiers such as an id from the data or you can use libraries such as uuid for a more robust solution. Also, remember it's important to note that hooks like useId() are not intended to not be used as keys.

šŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.

šŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.


2 Replies

  • There’s a native way to generate a UUID, via crypto.randomUUID(), just in case you were unaware. This can be added to each object in an array with the map method before returning the JSX.

  • Thanks a lot, Paul! Good point. Did not realize that crypto is now available in all browsers. Updated the article šŸ™‚

Leave a Reply

Your email address will not be published. Required fields are marked *