头图

The text starts here~

Overview

When we return from the map() method two or more elements with the same key attribute, the "Encountered two children with the same key" error is generated. To resolve this error, provide a unique value for each element's key attribute, or use an index parameter.

react-encountered-two-children-with-the-same-key.png

Here is an example to show how the error occurs.

 // App.js
const App = () => {
  // 👇️ name property is not a unique identifier
  const people = [
    {id: 1, name: 'Alice'},
    {id: 2, name: 'Bob'},
    {id: 3, name: 'Alice'},
  ];

  /**
   * ⛔️ Encountered two children with the same key, `Alice`.
   *  Keys should be unique so that components maintain their identity across updates.
   *  Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
   */
  return (
    <div>
      {people.map(person => {
        return (
          <div key={person.name}>
            <h2>{person.id}</h2>
            <h2>{person.name}</h2>
          </div>
        );
      })}
    </div>
  );
};

export default App;

The problem with the above snippet is that we are using the name attribute on each object as the key attribute, but the name attribute is not unique across the object.

index

One way to solve this problem is to use indexes. It is the second parameter passed to the map method.

 const App = () => {
  const people = [
    {id: 1, name: 'Alice'},
    {id: 2, name: 'Bob'},
    {id: 3, name: 'Alice'},
  ];

  // 👇️ now using index for key
  return (
    <div>
      {people.map((person, index) => {
        return (
          <div key={index}>
            <h2>{person.id}</h2>
            <h2>{person.name}</h2>
          </div>
        );
      })}
    </div>
  );
};

export default App;

The function we pass to the Array.map method is called with each element in the array and the index of the current element being processed.

The index is guaranteed to be unique, but using it for key property is not a best practice. Because it's not stable, it changes during rendering.

Uniquely identifies

A better solution is to use a value that uniquely identifies each element in the array.

In the above example, we can use the id attribute on the object, since each id attribute is guaranteed to be unique.

 // App.js
const App = () => {
  const people = [
    {id: 1, name: 'Alice'},
    {id: 2, name: 'Bob'},
    {id: 3, name: 'Alice'},
  ];

  // ✅ now using the id for the key prop
  return (
    <div>
      {people.map(person => {
        return (
          <div key={person.id}>
            <h2>{person.id}</h2>
            <h2>{person.name}</h2>
          </div>
        );
      })}
    </div>
  );
};

export default App;

Using id as the key attribute is much better. Because we guarantee that when the object id the property 1 , the name property is always equal to Alice .

React uses the value we pass to the key property for performance reasons to ensure it only updates list elements that change during rendering.

When each element in the array has a unique key it is easier for React to determine which list elements have changed.

You can use index as the key attribute. However, this may cause React to do more work behind the scenes than being as stable as the unique id property.

Still, unless you're rendering arrays with thousands of elements, chances are you won't notice any difference between using indexes and unique identifiers.


chuck
303 声望41 粉丝