Как избежать лишних перерисовок при использовании Context и почему Context — не менеджер состояния?
- Почему все компоненты перерисовываются при изменении контекста?
Все потребители контекста перерисовываются, когда value меняется по ссылке. Частая ошибка — объект в value создаётся заново на каждом рендере провайдера: value={{user, setUser}} — тогда перерисовываются все даже без изменений. Лечение: мемоизировать value (useMemo), разделять контексты (данные и функции отдельно, часто и редко меняющееся отдельно), опускать провайдер ниже. Context лишь доставляет значение — у него нет селекторов, подписки на часть, middleware; для сложного часто меняющегося состояния берут Zustand, Redux, Jotai.
- Компонент не может подписаться на часть контекста
- Функции из useState стабильны — их удобно класть в отдельный контекст
- React.memo не спасает от перерисовки потребителя контекста
А ещё Проверяйте Profiler'ом, прежде чем оптимизировать
Подробно
const value = useMemo(() => ({ user, login, logout }), [user]);
return <AuthCtx.Provider value={value}>{children}</AuthCtx.Provider>;Что хотят услышать
- Перерисовка при смене ссылки value.
- useMemo и разделение контекстов.
- Отсутствие селекторов — почему не менеджер состояния.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Потребители перерисовываются, только если изменилось именно то поле value, которое они используют
- ✗React.memo на потребителе полностью предотвращает перерисовку при смене контекста
- ✗Создавать объект value заново на каждом рендере — рекомендуемая практика
- ✓Мемоизировать value и делить контексты; Context лишь доставляет значение, без подписки на часть
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.