You may already know that, in React, we may map over a collection of items (Such as an array) using various iterator methods, such as Array.prototype.map or the trusty for loop outside JSX and generate Components or JSX Elements as we go.

You can learn more about Iterators in React in this article.

However, you might also notice a specific warning when doing so:

React Keys Warning - "Warning: Each child in a list should have a unique "key" prop."
React Keys Warning – “Warning: Each child in a list should have a unique “key” prop.”

So, what’s the issue, then?

What is a key in React?

It’s pretty often that whenever we are to render multiple components based on a mapping operation, we also want to maintain the orders of the components according to the data they’ve been mapped from.

From a developer’s perspective, it does seem straightforward. However, for React, on the other hand, it is a bit more complicated than that, especially when we consider multiple permutations and re-renders taking place in a React application’s lifecycle.

In order to help React identify which items have been changed, have been added, or have been removed, we usually pass down a key prop to each mapped component or JSX Element in order to establish an identity for each entity.

What makes a key prop unique?

You have most likely encountered the issue at hand and, after a bit of research into what React keys are, have decided to use the Array.prototype.map method’s second argument, which represents the position of the Element (first argument) inside the initial array:

{todos.map((todo, index) => (
  <div
    key={index}
    className="todo"
  >
    {todo.title}
  </div>
))}

That does seem like a good idea at first, but that’s until you see that it hasn’t solved the issue, and you’re greeted by the same red warning message again:

React Keys Warning - "Warning: Each child in a list should have a unique "key" prop."
React Keys Warning – “Warning: Each child in a list should have a unique “key” prop.”

React also uses that method under the hood; if you haven’t provided a unique prop key, React will use array indices as keys by default, so doing that yourself is redundant.

React expects a key whose value is not determined by the position of elements within the array we’re mapping from.

As long as it meets that criteria and it’s unique, it’s all good on React’s side.

Using Mapped List Item Data as Key

For this article, I’ve written a relatively small React application that looks something like this (It’s also the code generating the warning message):

import "./App.css";

function App() {
  const todos = [
    {
      title: "Wash the dishes",
    },
    {
      title: "Call Michael at 4:30 p.m.",
    },
    {
      title: "Appoint meeting with Charles on Wednesday",
    },
    {
      title: "Go to the golf course tomorrow",
    },
  ];

  return (
    <div className="App">
      <div className="todos-container">
        <h2>Todos</h2>
        {todos.map((todo, index) => (
          <div
            key={index}
            className="todo"
          >
            {todo.title}
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

We can generate unique React keys using what we have without the help of any other external or internal libraries.

That’s because the content of each of the items within the todos array is unique compared to the rest of the items in the array, which means we can use the title of each todo as the mapping key:

{todos.map((todo) => (
  <div key={todo.title} className="todo">
    {todo.title}
  </div>
))}

And that, as we can see by running the application, will do the job just fine:

Mapped List Item Data As React Prop Key

Generating React Keys

So we’ve seen how we would handle React keys when we have mapped lists with different content. However, what happens when we want to map, let’s say, the same data set n times?

In that case, we won’t be able to use the content as a key since it’s not unique.

What we can do instead is to generate a key on each mapping using a library such as uuid :

import { v4 } from "uuid";
import "./App.css";

function App() {
  const data = {
    title: "The same title",
    content: "The same content",
  };

  return (
    <div className="App">
      <div className="todos-container">
        <h2>Todos</h2>
        {[...Array(10).fill(data)].map((item) => {
          const uniqueKey = v4();

          return (
            <div key={uniqueKey}>
              <h2>{item.title}</h2>
              <p>{item.content}</p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default App;

Which, frankly, should give us the same DevTools result:

Mapped Data With Uuid Unique Key
Mapped Data With Uuid Unique Key

Summary

Although in most cases, the keys would be granted by the Back-End as entities’ ids, there are edge scenarios where we might need to generate them ourselves, thus today’s article.

I hope you have enjoyed the read and got a better understanding of what React Keys are, why React requires them, and, more importantly, how we can generate or pass React keys down to components that are mapped from a list.

Feel free to let me know in the comments section below if you feel I’ve missed anything or if you have any feedback for this article.

Cheers!

👋 Hey, I'm Vlad Mihet
I'm Vlad Mihet, a blogger & Full-Stack Engineer who loves teaching others and helping small businesses develop and improve their technical solutions & digital presence.

💬 Leave a comment

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

We will never share your email with anyone else.