javascript – What is it for and how to set the prop "key" in React?

Question:

When rendering a dynamic list in React or React Native, I get the following warning:

Warning: Each child in a list should have a unique "key" prop.

Despite that, things seem to work fine without the prop key . See this example :

function shuffleArray(array) {
  var currentIndex = array.length,
    randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {
    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;

    // And swap it with the current element.
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex],
      array[currentIndex]
    ];
  }

  return array;
}

function App() {
  const [pokemons, setPokemons] = React.useState([
    {
      name: "Bulbasaur",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/001.png"
    },
    {
      name: "Ivysaur",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/002.png"
    },
    {
      name: "Venusaur",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/003.png"
    },
    {
      name: "Charmander",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/004.png"
    },
    {
      name: "Charmeleon",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/005.png"
    },
    {
      name: "Charizard",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/006.png"
    },
    {
      name: "Squirtle",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/007.png"
    },
    {
      name: "Wartortle",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/008.png"
    },
    {
      name: "Blastoise",
      img: "https://assets.pokemon.com/assets/cms2/img/pokedex/detail/009.png"
    }
  ]);

  function shuffle() {
    setPokemons(shuffleArray([...pokemons]));
  }

  return (
    <ul>
      <button onClick={shuffle}>Embaralhar</button>
      {pokemons.map((pokemon) => (
        <li onClick={() => console.log(pokemon.name)}>
          <img src={pokemon.img} alt={pokemon.name} />
          <span>{pokemon.name}</span>
        </li>
      ))}
    </ul>
  );
}

ReactDOM.render(<App /> , document.querySelector("#app"));
ul {
  padding-right: 2rem;
  padding-left: 2rem;
}

li {
  list-style: none;
  display: flex;
  align-items: center;
  padding: 10px;
  border: 2px solid #ccc;
}

li:hover {
  background-color: #deebff;
  cursor: pointer;
}

img {
  height: 40px;
  width: 40px;
}

span {
  font-size: 20px;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="app"></div>

To solve this warning, I've already found several answers here using the index as a key , so I have the following questions:

  • What is this key property for?

  • Do I need to set a key only when traversing an array?

  • How can I set a key? Can I use the index, a random number or is there a better way?

Answer:

What is this key property for

To uniquely identify each element or component that will be created, altered, deleted and/or selected from a list of values ​​( array ), that is, it is linked to the creation of dynamic elements of any list that need to have uniqueness .

Do I need to set a key only when traversing an array ?

In fact the correct question: When using an array to create dynamic elements is it necessary to use a unique identifier ( key ) ?

Yes, when creating an element or component it is necessary to pass an identifier so that React knew which elements were created, changed, deleted and/or selected.

In general, this is how React verifies changes in its elements exactly so that in the end the performance is not compromised, but this is not the only thing that makes React perform better, there are more techniques for this happen.

The caveat to the question is that key is only used when creating dynamic elements from an array . An array can have other purposes such as: filters, creating new arrays and not using the component's key .

How can I set a key? Can I use the index, a random number or is there a better way?

It is not ideal to use the index of an array to identify elements or components and the predominant reason is that changes in the ordering of these values ​​can happen (which include any changes in this array as insertions of new values, deletions of list items and order changes ) which can impact performance and unnecessarily render renderings, causing slowdowns and errors. If your list doesn't undergo any of these actions, you can even use the array index as a unique ( particularly prefer not to use ), for example, a display list of values ​​that doesn't undergo any modification and will only serve as a display.

In a list that the items have a unique identification such as id of a database table or some repository, its use is highly recommended, another way is to use codes in ready-made packages such as uniqueid and nanoid , generating also in this case a full identification of each element.

Do not use codes that can cause or have a chance of causing duplication and thus breaking the main reason for the existence of the key to identify which element was modified.

References

Scroll to Top