Выбор ответа Middle Состояние и useState/useReducer обновлено

Мутация в редьюсере

Вопрос

Почему после dispatch({ type: "added", text }) список на экране не меняется?

function reducer(state, action) {
  if (action.type === 'added') {
    state.push({ text: action.text });
    return state;
  }
  return state;
}

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

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

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

Коротко

Правильный ответ: Редьюсер мутирует массив и возвращает ту же ссылку. Редьюсер обязан возвращать новое значение. push меняет исходный массив, и возвращается та же ссылка, а Object.is говорит, что ничего не изменилось.

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

  1. Редьюсер мутирует массив и возвращает ту же ссылкуправильный ответ
  2. useReducer не умеет работать с массивами в state
  3. Нужно вызывать dispatch через функциональный апдейтер
  4. dispatch асинхронный, изменения появятся позже

Разбор

Редьюсер обязан возвращать новое значение. push меняет исходный массив, и возвращается та же ссылка, а Object.is говорит, что ничего не изменилось. Правильно: return [...state, { text: action.text }]. Массивы в useReducer хранить можно. Функциональной формы у dispatch нет. «Позже» изменения тоже не появятся.

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

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