Что будет, если передать в React diff div без key
Что проверяют
Понимаете ли вы, как React сопоставляет старое и новое дерево, и отличаете ли случай, где отсутствие ключа даёт настоящий баг, от случая, где это просто предупреждение в консоли.
Как отвечать
Сначала уточните контекст. Одиночный div в разметке ключа не требует вовсе, ключи нужны только детям, которые приходят массивом, обычно из map. Без ключа в режиме разработки React пишет предупреждение о том, что каждый элемент списка должен иметь уникальный key, и сопоставляет элементы по позиции.
Пока список только дополняется в конец, разницы вы не увидите. Ломается всё при вставке в начало, удалении из середины и сортировке: React считает, что первый элемент так и остался первым, и переиспользует его узел с новыми пропсами. Текст и атрибуты при этом обновятся правильно, а всё, что живёт внутри узла и не приходит из пропсов, останется от прежнего элемента:
- значение неконтролируемого поля ввода и позиция курсора;
- фокус, прокрутка, проигрываемое видео;
- локальное состояние дочернего компонента;
- запущенная анимация, которая не перезапустится.
Ключ должен быть стабильным и уникальным среди соседей, обычно это идентификатор из данных. Индекс годится только для списка, который не переупорядочивается и не фильтруется.
Где спотыкаются
Ставят индекс ключом и считают вопрос закрытым. Для перемешиваемого списка это ровно то же поведение, что и без ключа: предупреждение исчезло, а сопоставление осталось позиционным.
Второе: берут случайное число. Ключ меняется на каждом рендере, поэтому React удаляет старые узлы и создаёт новые: теряются состояние и фокус, а к неправильному поведению добавляется лишняя работа с DOM.
Третье: объясняют отсутствие ключа только просадкой скорости. Основная цена это чужое состояние в переставленных элементах, а лишние операции с DOM вторичны и обычно незаметны.