Выбор ответа Middle Context и стейт-менеджеры обновлено

Селектор Zustand, возвращающий объект

Вопрос

Проект на Zustand v5. Что произойдёт с этим компонентом?

const useUser = create((set) => ({ name: 'Аня', age: 30, setName: (name) => set({ name }) }));

function Profile() {
  const { name, age } = useUser((s) => ({ name: s.name, age: s.age }));
  return <p>{name}, {age}</p>;
}

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

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

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

Коротко

Правильный ответ: Селектор отдаёт новый объект: в v5 цикл, нужен useShallow. По умолчанию Zustand сравнивает результат селектора через Object.is.

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

  1. Всё нормально: Zustand сам сравнивает объекты поверхностно
  2. Селектор отдаёт новый объект: в v5 цикл, нужен useShallowправильный ответ
  3. Компонент не будет обновляться при изменении name в сторе
  4. Ошибка при сборке: селектор Zustand должен возвращать примитив

Разбор

По умолчанию Zustand сравнивает результат селектора через Object.is. Новый объект на каждый вызов означает «изменилось всегда». В v5 стор работает через useSyncExternalStore, и нестабильный снимок даёт ошибку Maximum update depth exceeded. Решения: useShallow((s) => ({ name: s.name, age: s.age })) или два вызова useUser((s) => s.name) и useUser((s) => s.age).

  • Поверхностного сравнения по умолчанию нет, его включает useShallow.
  • Обновляться компонент будет, проблема в лишних, а не пропущенных обновлениях.
  • Возвращать объект можно, если сделать его стабильным.

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

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

Термины по теме