← Назад к вопросам

Что будет если использовать index в качестве key в JSX?

2.0 Middle🔥 111 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ответ: Использование index в качестве key в JSX — опасная практика

Прямой ответ: если использовать index массива как значение для key в React, это может привести к некорректному поведению списков, особенно при операциях добавления, удаления, сортировки или фильтрации элементов. React будет путать компоненты, что вызывает проблемы с состоянием, производительностью и может приводить к ошибкам в UI.

Почему key так важна в React?

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

  • Что нужно добавить.
  • Что нужно удалить.
  • Что можно обновить (реиспользовать).

Без стабильных и уникальных key React может:

  • Неоптимально обновлять DOM (пересоздавать элементы вместо их обновления).
  • Путать состояние компонентов между элементами (например, значения в инпутах, фокус, анимации).

Конкретные проблемы при использовании index как key

1. Некорректное сопоставление состояния при изменении порядка списка

Рассмотрим пример: список задач с чекбоксами, где состояние «выбрано» хранится в компонете. Если удалить первый элемент, все индексы сдвинутся.

// Изначальный список — index как key
const initialTasks = ['Task A', 'Task B', 'Task C'];
// Рендер:
{initialTasks.map((task, index) => (
  <TaskItem key={index} task={task} />
))}

// TaskItem может иметь внутреннее состояние (например, isChecked)
// Пусть пользователь выбрал Task B (index=1).

Если мы удалим Task A:

const newTasks = ['Task B', 'Task C']; // Task B теперь имеет index=0
// React увидит:
// - key=0 (старый: Task A, новый: Task B) → считает, что это тот же элемент, обновит проп, но состояние (isChecked) останется от Task A!
// - key=1 (старый: Task B, новый: Task C) → состояние от Task B перейдёт к Task C!

Результат: состояние чекбоксов переместится между элементами, что полностью нарушает логику интерфейса.

2. Проблемы с производительностью

React может реиспользовать DOM-узлы неправильно. Например, при добавлении элемента в начало списка, все индексы изменятся, и React решит, что каждый элемент изменился, и будет пересоздавать DOM вместо перемещения существующих узлов.

// Добавляем элемент в начало — все индексы меняются
const oldList = items.map((item, index) => <div key={index}>{item}</div>);
const newList = [newItem, ...items].map((item, index) => <div key={index}>{item}</div>);
// React не сможет понять, что старый элемент с key=0 теперь стал key=1,
// и перерендерит все div, даже если их содержимое не изменилось.

3. Ошибки при фильтрации или сортировке

Аналогично — если список фильтруется (например, удаляются некоторые элементы), индексы изменятся хаотично, и React сопоставит элементы некорректно.

4. Проблемы с анимациями или фокусом

Компоненты могут иметь неконтролируемое состояние (фокус в input, переходы CSS). При изменении индексов это состояние может «прилипнуть» к неправильным элементам.

Правильный подход: что использовать вместо index?

key должна быть:

  • Уникальной среди соседних элементов в списке.
  • Стабильной — не меняться между рендерами для одного и того же элемента.
  • Не случайной — не генерироваться на каждом рендере (например, Math.random()).

Идеальные источники для key:

  • Уникальный ID из данных (например, id из API).
{users.map(user => (
  <UserItem key={user.id} user={user} />
))}
  • Если ID нет, можно генерировать уникальную комбинацию (например, name + timestamp), но это должно быть стабильно.

  • Для статических списков, которые никогда не изменяются (очень редкий случай), index допустим, но лучше избегать.

Когда index может быть условно приемлем?

Только если:

  • Список абсолютно статичен (не изменяется порядок, не добавляются/удаляются элементы).
  • Элементы списка не имеют внутреннего состояния.
  • Не используются анимации, зависящие от идентификатора элемента.

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

Вывод и рекомендации

Никогда не используйте index как key для динамических списков. Это классическая ошибка, которая приводит к:

  • Корректным, но неожиданным багам в состоянии компонентов.
  • Снижению производительности.
  • Потенциальным проблемам с accessibility (например, потеря фокуса).

Правильная практика: всегда доставайте уникальный идентификатор из ваших данных. Если его нет (например, список строк), можно рассмотреть хэширование содержимого или другие стабильные методы, но index — опасный выбор. React документация прямо предостерегает от этого, подчеркивая, что key должны быть уникальными и стабильными для корректной работы диффа и сохранения состояния.

Что будет если использовать index в качестве key в JSX? | PrepBro