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

Зачем нужен атрибут Key?

2.2 Middle🔥 251 комментариев
#React#Vue.js#Оптимизация и производительность

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Атрибут Key в React: Назначение и значимость

Attrибут key в React — это специальный идентификатор для элементов списка, который помогает React отслеживать, какие элементы изменились, добавились или удалились. Это не просто деталь реализации, а фундаментальный механизм, влияющий на производительность и корректность работы приложения.

Основная проблема без Key

Когда React рендерит список без key, он основывается только на позиции элемента в массиве:

// ❌ Плохо — без key
const TodoList = ({ items }) => (
  <ul>
    {items.map((item, index) => (
      <li key={index}>{item.text}</li>
    ))}
  </ul>
);

Проблема: если удалить или переместить элемент, React подумает, что это другой элемент, и:

  • Потеряет состояние компонента (значения форм, фокус)
  • Переиспользует DOM-узлы неправильно
  • Рассинхронизирует данные с UI
  • Снизит производительность

Правильное использование Key

Используй уникальный стабильный идентификатор из данных:

// ✅ Хорошо — с уникальным id
const TodoList = ({ items }) => (
  <ul>
    {items.map((item) => (
      <li key={item.id}>{item.text}</li>
    ))}
  </ul>
);

Почему это работает:

  • React знает, какой элемент в массиве соответствует какому DOM-узлу
  • Если порядок изменится, элемент остаётся привязан к своему DOM-узлу
  • Состояние компонента сохраняется
  • DOM-узлы переиспользуются правильно

Практический пример проблемы

const Input = ({ value, onChange }) => (
  <input value={value} onChange={onChange} />
);

const App = () => {
  const [items, setItems] = useState([
    { id: 1, name: "Alice" },
    { id: 2, name: "Bob" },
  ]);
  const [inputs, setInputs] = useState({ 1: "", 2: "" });

  // ❌ Без key — после удаления Alice, Bob получит старное значение от Alice!
  const moveToEnd = () => {
    setItems([items[1], items[0]]);
  };

  return (
    <>
      {items.map((item, index) => (
        <div key={index}>
          <h3>{item.name}</h3>
          <Input
            value={inputs[item.id]}
            onChange={(e) => setInputs({ ...inputs, [item.id]: e.target.value })}
          />
        </div>
      ))}
      <button onClick={moveToEnd}>Swap</button>
    </>
  );
};

После клика на "Swap" input, который был у Bob, теперь будет отображать значение Alice!

✅ Решение:

{items.map((item) => (
  <div key={item.id}>
    {/* Теперь input остаётся привязан к correct item */}
  </div>
))}

Ключевые правила

  1. Никогда не используй index как key (кроме статичных списков, где нет реордеринга)
  2. Key должен быть уникален в рамках списка
  3. Key должен быть стабильным — не меняться при рендере
  4. Используй реальный id из данных

Key — это критическая часть React-архитектуры, и неправильное его использование приводит к сложным багам, которые трудно отловить.