Ответ вслух Middle Код-ревью спрашивают часто обновлено

Ревью: провайдер состояния

Вопрос

Перед тобой код на ревью. Скажи вслух, что здесь не так - по убыванию важности.

Читай вслух, как на ревью: сначала что делает код, потом что сломано.

function AppProvider({ children }) {
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState('light');
  const [cart, setCart] = useState([]);

  return (
    <AppContext.Provider value={{ user, setUser, theme, setTheme, cart, setCart }}>
      {children}
    </AppContext.Provider>
  );
}

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Новый объект каждый рендер. Литерал в value создаёт новую ссылку, и React перерисовывает все компоненты, читающие контекст, - даже если ни одно поле не менялось.

Что должно прозвучать в ответе

  • value - новый объект на каждом рендере, перерисовываются все потребители

  • нужен useMemo по зависимостям

  • всё состояние в одном контексте: смена корзины перерисовывает потребителей темы

  • разделить на несколько контекстов по частоте изменения

  • отделить данные от функций-действий - действия стабильны

  • memo у потребителей контекста не спасёт

Что могут спросить следом

  • Как разделить контекст на данные и действия?
  • Когда пора уходить с контекста на внешний стор?

Разбор

Новый объект каждый рендер. Литерал в value создаёт новую ссылку, и React перерисовывает все компоненты, читающие контекст, - даже если ни одно поле не менялось. React.memo тут не помогает: подписка на контекст обходит сравнение пропсов.

Один контекст на всё. Даже с useMemo остаётся структурная проблема: добавление товара в корзину перерисует компонент, которому нужна только тема. Контекст обновляется целиком, подписаться на поле нельзя.

Правильно - разделить по частоте изменения: ThemeContext, UserContext, CartContext. И отдельно разнести данные и действия: setUser стабилен между рендерами, значит контекст действий можно мемоизировать с пустыми зависимостями, и его потребители не будут перерисовываться никогда.

Если обновления частые и точечные - контекст вообще не тот инструмент, нужен стор с подпиской на срез.

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

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