React 中 Encountered two children with the same key 错误

当我们从 map() 方法返回的两个或多个元素具有相同的键属性时,会出现 React 错误“Encountered two children with the same key”。 要解决该错误,需要为每个元素的 key prop 提供唯一值或使用 index 参数。

看下面的代码

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;

React 中 Encountered two children with the same key 错误

代码片段中的问题是我们在每个对象上使用名称作为 key 属性,但名称属性在所有对象中并不是唯一的。

解决错误的一种方法是使用索引,它是传递给 map() 方法采用的函数的第二个参数。

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;

我们传递给 Array.map 方法的函数被调用,其中包含数组中的每个元素以及正在处理的当前元素的索引。

更好的解决方案是使用一个值来唯一标识数组中的每个元素。

在示例中,我们可以在对象上使用 id 属性,因为每个 id 都保证是唯一的。

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;

使用 id 作为 key 属性要好得多,因为我们保证 id 为 1 的对象将始终具有等于 Alice 的 name 属性。

当数组中的每个元素都有一个唯一的键时,React 可以更容易地确定哪些列表元素发生了变化。

话虽如此,除非您呈现包含数千个元素的数组,否则您很有可能不会注意到使用索引和唯一标识符之间的任何区别。

总结

当我们从 map() 方法返回的两个或多个元素具有相同的键属性时,会出现 React 错误“Encountered two children with the same key”。要解决该错误,请为每个元素的 key prop 提供唯一值或使用 index 参数。