Выбор ответа Middle Компоненты на практике спрашивают часто обновлено

Индекс как key и состояние строк

Вопрос

В списке у каждой строки свой <input> с введённым текстом (неконтролируемый). После удаления первой строки текст «съезжает» на соседнюю. Почему?

{todos.map((todo, i) => (
  <li key={i}>
    {todo.title} <input placeholder="заметка" />
    <button onClick={() => remove(todo.id)}>Удалить</button>
  </li>
))}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: key это индекс: после удаления ключ 0 у другой строки. React сопоставляет элементы между рендерами по key.

Варианты ответа

  1. Удаление через filter мутирует исходный массив, и строки сдвигаются
  2. key это индекс: после удаления ключ 0 у другой строкиправильный ответ
  3. React не умеет удалять элементы из середины списка без перерисовки
  4. Строку нужно обернуть в memo, иначе React теряет её состояние

Разбор

React сопоставляет элементы между рендерами по key. При ключах-индексах после удаления первой строки бывшая вторая получает ключ 0, и React считает её той же строкой, переиспользуя DOM-узел с введённым текстом. Нужен стабильный key={todo.id}.

  • filter возвращает новый массив и не мутирует исходный.
  • Удаление из середины React делает нормально при корректных ключах.
  • memo не влияет на сопоставление элементов.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.