Почему возникает ошибка "Each child in a list should have a unique «key» prop"?

Как исправить ошибку "Each child in a list should have a unique 'key' prop" при использовании key={Math.random()} в компоненте списка и элементах списка?
  • 2 февраля 2024 г. 12:40
Ответы на вопрос 2
Ошибка "Each child in a list should have a unique 'key' prop" возникает в React приложениях, когда разработчик не предоставляет уникальный атрибут `key` для элементов списка при их рендеринге. Атрибут `key` помогает React определять, какие элементы изменяются, добавляются или удаляются, что обеспечивает эффективные обновления DOM.

Использование `key={Math.random()}` не является хорошей практикой, потому что это создает новый уникальный ключ каждый раз при перерендеринге компонента, что приведет к потере преимуществ, связанных с переиспользованием и оптимизацией компонентов в списках. React не сможет корректно определить, какие элементы остались теми же, и будет перерендеривать весь список, что негативно скажется на производительности приложения.

Чтобы исправить эту ошибку, следует использовать стабильные, предсказуемые и уникальные значения в качестве ключей. Чаще всего для ключей используются уникальные идентификаторы, которые предоставляются вместе с данными, например, ID из базы данных.

Пример без ошибки:

```javascript
const items = [
  { id: 1, text: 'Item 1' },
  { id: 2, text: 'Item 2' },
  { id: 3, text: 'Item 3' },
  // и так далее
];

return (
  <ul>
    {items.map(item => (
      <li key={item.id}>
        {item.text}
      </li>
    ))}
  </ul>
);
```

В этом примере каждому элементу списка (`li`) присваивается уникальное значение `key`, соответствующее свойству `id` объекта элемента списка, что является хорошей практикой для ключей в React.

Если у вас нет уникальных идентификаторов, но можете гарантировать уникальность и стабильность других данных (например, имя или другое уникальное свойство элемента), то это тоже можно использовать в качестве ключа:

```javascript
const items = [
  { name: 'uniqueName1', text: 'Item 1' },
  { name: 'uniqueName2', text: 'Item 2' },
  { name: 'uniqueName3', text: 'Item 3' },
  // и так далее
];

return (
  <ul>
    {items.map(item => (
      <li key={item.name}>
        {item.text}
      </li>
    ))}
  </ul>
);
```

Примечание: если вы абсолютно уверены, что порядок элементов не изменится и элементы не будут добавляться или удаляться, индекс элемента в массиве может быть использован как ключ. Однако это часто не рекомендуется, так как может привести к непредвиденным проблемам с производительностью и состоянием компонента при обновлениях списка.
key надо выставлять не для Crumb, а для фрагмента: 

ну и Math.random() для key - худшее, что ты мог придумать. Наверняка у crumb есть какой-нибудь id, вот его и надо использовать. Или, например, path, title, - что-то из них ведь уникальное, не повторяется в массиве crumbs?
на крайний случай можно idx
Похожие вопросы