Можно ли использовать индекс в качестве значения атрибута key?

🎯 Зачем спрашивают
Интервьюер проверяет понимание механизма reconciliation и принципов identity в React. Этот вопрос показывает, знает ли кандидат, зачем нужен key и как React оптимизирует diffing.
 
📝 Ответ
Коротко: Да, можно, но с оговорками. Лучше всего это делать для кортежей (массивов с константным кол-во элементов). Если использовать key={index} на динамическом массиве, то это может привести к непредсказуемому поведению и UI багам.
 
index как значение key допустим:
  • список статичен и никогда не меняется;
  • список генерируется один раз и не редактируется пользователем;
  • список без внутреннего состояния (только рендер контента).
 
Подробнее:
React использует ключи (key), чтобы понимать, какие элементы добавились, удалились или поменяли порядок в списках, чтобы при изменениях можно было эффективно обновить DOM, не перерисовывая всё заново. 👉 Подробнее
 
При использовании key={index}, например:
{items.map((item, index) => ( <ListItem key={index} value={item} /> ))}
React не может корректно сопоставить элементы, если:
  • список изменяется (добавление, удаление, перестановка элементов);
  • порядок элементов меняется динамически.
 
Это приводит к багам:
  • неправильное сохранение состояния элементов (например, инпуты "перескакивают");
  • неожиданное поведение анимаций или переходов;
  • неэффективное обновление DOM (React не понимает, что элемент просто переместился).
 
👉 Пример бага
import { useState } from 'react'; export default function App() { const [items, setItems] = useState(['Аня', 'Борис', 'Вика']); const removeFirst = () => { setItems((prev) => prev.slice(1)); }; return ( <div> <button onClick={removeFirst}>Удалить первого</button> {items.map((name, index) => ( <Input key={index} value={name} /> ))} </div> ); } function Input({ value }) { const [text, setText] = useState(value); return ( <div style={{ marginBottom: 8 }}> <input value={text} onChange={(e) => setText(e.target.value)} /> </div> ); }
Решение проблемы:
{items.map((name) => ( <Input key={name} value={name} /> ))}
 
Если массив мутировать (добавить элемент в начало или удалить любой элемент, кроме последнего) это приведет к перерасчету индексов, они сместятся. А значит, изменится и key у React элементов, что приведет к размонтированию и повторному монтированию.
 
 
⚖️ Компромиссы
✅ Плюсы
❌ Минусы
Использование index просто и быстро, подходит для статичных списков.
Но ломает сохранение состояния и анимации при динамических изменениях.
 
🔎 Встречные вопросы
  • Что будет, если у двух элементов одинаковые key?
  • Что произойдёт, если key будет меняться при каждом рендере (например, Math.random())?
 
🚩 Красные флаги
  • Нельзя использовать индекс вообще никогда (жёсткий категоричный ответ)
  • Это влияет только на перформанс (показывает непонимание сути проблемы).
  • key нужен, чтобы React быстрее работал (неправильно — он нужен для идентификации).
 
🛠 Практика
 
📚 Источники / ссылки