PassFront
  1. PassFront
  2. База знаний
  3. Компоненты

Разбери, можно ли в key в React использовать индекс массива: при каких условиях и какие ограничения.

Компоненты

Использовать индекс массива как key можно, но только при строгих условиях; во всех остальных случаях это источник трудноуловимых багов.

Когда индекс допустим

Все три условия одновременно:

  • список статичен: элементы не добавляются, не удаляются, не сортируются и не фильтруются;
  • у элементов нет состояния (инпутов, чекбоксов, анимаций) и они не мемоизированы;
  • у данных нет стабильного id (или элементы — примитивы вроде строк подсказок).

Пример: фиксированный список преимуществ на лендинге, скелетоны-заглушки.

Почему индекс опасен в изменяемом списке

Индекс привязан к позиции, а не к данным. При удалении первого элемента все последующие «переезжают» на чужие ключи:

{todos.map((todo, i) => <TodoItem key={i} todo={todo} />)}
// удалили todos[0]:
// key=0 теперь другой todo — React обновит props, но СОСТОЯНИЕ узла останется

Последствия:

  • введённый текст/чекбокс «перепрыгивает» на соседнюю строку;
  • лишние перерендеры: изменились «все» элементы, а не один удалился;
  • ломаются анимации появления/удаления и восстановление фокуса.

Отдельный антипаттерн — key={Math.random()}: элементы пересоздаются каждый рендер.

Что использовать вместо

  • id из данных (БД, uuid при создании записи на клиенте);
  • стабильный композитный ключ (${type}-${slug});
  • если id нет вообще — сгенерировать при получении данных один раз (не в рендере).

Коротко для собеседования

Индекс как key допустим только для полностью статичного списка без состояния элементов. При вставках/удалениях/сортировке индексы переезжают на другие данные: состояние строк путается, рендеры лишние, анимации ломаются. Правило: стабильный id из данных; индекс — осознанное исключение.

Другие вопросы раздела