Выбор ответа Junior Объекты и массивы спрашивают часто обновлено

push в массив состояния React

Вопрос

Почему после вызова add список на экране не обновляется?

const [items, setItems] = useState([]);
function add(item) {
  items.push(item);
  setItems(items);
}

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

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

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

Коротко

Правильный ответ: Ссылка на массив та же, Object.is даёт true, и React пропускает обновление. React сравнивает новое состояние со старым через Object.is. push мутирует тот же массив, и в setItems уходит та же ссылка, поэтому React решает, что ничего не изменилось.

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

  1. useState отслеживает только длину массива, а она меняется уже после рендера
  2. setItems асинхронный и выполнится позже, когда компонент перерисуется сам
  3. push запрещён для массивов из useState: React замораживает их в разработке
  4. Ссылка на массив та же, Object.is даёт true, и React пропускает обновлениеправильный ответ

Разбор

React сравнивает новое состояние со старым через Object.is. push мутирует тот же массив, и в setItems уходит та же ссылка, поэтому React решает, что ничего не изменилось. Правильно: setItems((prev) => [...prev, item]). Длину React не отслеживает, он сравнивает только ссылку. Отложенность обновления не объясняет, почему оно не происходит вообще. Массив из useState обычный и не заморожен, push по нему работает, но мутировать состояние нельзя по смыслу.

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

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