Вопрос проверяет понимание проблем, возникающих при использовании индекса массива в качестве ключа (key) в React при удалении элемента из списка.
В React при рендеринге списков с помощью map() требуется задавать уникальный key для каждого элемента. Ключи помогают React эффективно сравнивать виртуальный DOM между обновлениями, определяя, какие элементы были добавлены, изменены или удалены.
Если в качестве ключа используется индекс элемента в массиве, это может привести к серьёзным проблемам при изменении порядка элементов (сортировка, добавление, удаление). Рассмотрим пример списка задач, где каждая задача имеет поле ввода.
const TaskList = () => {
const [tasks, setTasks] = useState([
{ id: 1, text: 'Task A' },
{ id: 2, text: 'Task B' },
{ id: 3, text: 'Task C' },
]);
const removeTask = (indexToRemove) => {
setTasks(tasks.filter((_, index) => index !== indexToRemove));
};
return (
{tasks.map((task, index) => (
removeTask(index)}>Delete
))}
);
};Предположим, пользователь ввёл "Updated B" во втором поле ввода (индекс 1), а затем удалил первую задачу (индекс 0). После удаления массив задач изменится: элемент с id=2 (старый индекс 1) станет первым (новый индекс 0). Однако React, видя ключи 0, 1, 2, подумает, что элемент с key=0 (старая задача A) удалён, а элементы с key=1 и key=2 просто сдвинулись вверх. В результате состояние ввода ("Updated B") останется привязанным к ключу 1, который теперь соответствует задаче C, а не задаче B. Пользователь увидит, что его ввод "перепрыгнул" на другую строку.
Вместо индекса следует использовать стабильный уникальный идентификатор из данных, например, task.id. Тогда React сможет правильно отслеживать каждый элемент независимо от его позиции в списке.
{tasks.map((task) => (
removeTask(task.id)}>Delete
))}Это гарантирует, что состояние компонента (включая локальное состояние ввода, фокус и другие атрибуты DOM) будет корректно сохранено для правильного элемента даже после изменений в списке.
Вывод: Использование индекса в качестве ключа допустимо только для статических списков, которые никогда не меняют порядок, не фильтруются и не имеют состояния. В динамических списках всегда применяйте уникальные стабильные ключи из данных, чтобы избежать скрытых ошибок и непредсказуемого поведения интерфейса.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию