> Почему нельзя использовать индекс массива как ключ в React (React)

Уровень: middle · Роль: frontend · Категория: Технические вопросы

Компании: Kaspersky, Exness

Стек: React

> Пример ответа

Короткий ответ

Использование индекса массива как key в React не рекомендуется, потому что при изменении порядка элементов (добавление, удаление, сортировка) индексы пересчитываются, что приводит к неправильному сопоставлению старых и новых элементов. React использует key для идентификации элементов, и при смене key компонент пересоздаётся, а не обновляется, что вызывает потерю состояния и лишние перерисовки.

Подробное объяснение

React использует key для оптимизации процесса reconciliation - сопоставления виртуального DOM с реальным. Когда React обновляет список, он сравнивает key текущих элементов с key предыдущих. Если key остаётся тем же, React обновляет существующий элемент; если key меняется - создаёт новый.

Индекс массива как key приводит к проблемам в следующих сценариях:

  • Добавление элемента в начало: все последующие элементы получают новые индексы, React пересоздаёт их, хотя они не изменились
  • Удаление элемента: индексы сдвигаются, React неправильно сопоставляет старые и новые элементы
  • Сортировка: каждый элемент получает новый индекс, теряется состояние (input, scroll, фокус)

Исключение - статический список, который никогда не изменяется (не добавляется, не удаляется, не сортируется). Но даже в этом случае лучше использовать уникальный идентификатор, чтобы избежать проблем при рефакторинге.

На практике

  • Всегда используйте уникальный и стабильный идентификатор из данных (id, uuid, slug)
  • Если данных нет, генерируйте id при создании элемента (например, через библиотеку uuid)
  • Для статических списков без изменений индекс допустим, но это антипаттерн
  • В формах с динамическими полями индекс как key приведёт к потере ввода при добавлении/удалении полей

Пример кода

JSX
// ❌ Плохо: индекс как key
const List = ({ items }) => (
<ul>
{items.map((item, index) => (
<li key={index}>{item.text}</li>
))}
</ul>
);
// ✅ Хорошо: уникальный id
const List = ({ items }) => (
<ul>
{items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
// ✅ Для статического списка без изменений - допустимо, но не рекомендуется
const StaticList = () => (
<ul>
{['a', 'b', 'c'].map((char, index) => (
<li key={index}>{char}</li>
))}
</ul>
);

Как отвечать на собеседовании

Начните с ключевой проблемы - неправильное сопоставление элементов при изменении списка. Объясните механизм reconciliation и как key влияет на производительность и состояние. Приведите конкретный пример с потерей состояния input при добавлении элемента в начало. Упомяните исключение для статических списков, но подчеркните, что это антипаттерн. Закончите рекомендацией использовать уникальные идентификаторы.

Что проверяет интервьюер

  • Понимание механизма reconciliation в React
  • Знание, как key влияет на перерисовку и сохранение состояния
  • Умение предвидеть последствия неправильного выбора key
  • Практический опыт работы с динамическими списками

Типичные ошибки

  • Утверждение, что индекс никогда нельзя использовать - это неверно для статических списков
  • Путаница между key и ref
  • Игнорирование проблемы с состоянием input при динамических списках
  • Предложение использовать random() или Date.now() как key - это приводит к пересозданию всех элементов при каждом рендере

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью