0Pricing
React Academy · Урок

Паттерн селектора контекста

Реализуйте простой хук-селектор, который перерисовывает компонент только при изменении части контекста.

«Паттерн селектора контекста» — бесплатный урок React Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Добро пожаловать

В этом уроке Вы реализуете хук-селектор контекста, который подписывает компонент только на часть состояния контекста и предотвращает повторные рендеринги при изменении несвязанных частей контекста.

Проблема селектора

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

Что такое селектор

Селектор — это функция, извлекающая определённую часть состояния из более крупного объекта состояния: `state => state.user.name`. Хук-селектор подписывается на контекст, но вызывает повторный рендеринг только при изменении выбранного значения.

Простой хук-селектор

Создайте хук useSelector, который читает контекст и оборачивает результат в useMemo. Компонент повторно отрисовывается только при изменении выбранного значения.
function useAppSelector(selector) {
  const state = useContext(AppCtx);
  return useMemo(() => selector(state), [state, selector]);
}

// Consumer only re-renders when user.name changes
const name = useAppSelector(s => s.user.name);

Проверка поверхностного равенства

useMemo с селектором всё равно вызывает повторный рендеринг, если селектор при каждом вызове возвращает новую ссылку на объект или массив, например `s => s.items.filter(...)`. Используйте сравнение на поверхностное равенство, чтобы пропускать повторные рендеринги, когда содержимое не изменилось.
import { useRef } from 'react';

function useSelector(selector) {
  const state = useContext(AppCtx);
  const selected = selector(state);
  const ref = useRef(selected);
  if (!shallowEqual(ref.current, selected)) {
    ref.current = selected;
  }
  return ref.current;
}

Библиотека use-context-selector

Для использования в готовых приложениях библиотека **use-context-selector** предоставляет хук useContextSelector с эффективной подпиской и проверкой равенства — без необходимости во внешних менеджерах состояния.
import { useContextSelector } from 'use-context-selector';

const name = useContextSelector(AppCtx, s => s.user.name);

Zustand как нативное решение с селекторами

Хук `useStore(selector)` из Zustand имеет встроенную поддержку селекторов и поверхностного равенства из коробки, поэтому хорошо подходит для больших деревьев состояния, где важны детализированные подписки.
const name = useAppStore(state => state.user.name);

Когда селекторы избыточны

Если контекст обновляется редко, а потребители дёшевы в повторном рендеринге, селекторы добавляют сложность без измеримой пользы. Сначала выполняйте профилирование — всегда оптимизируйте на основе фактов.

Мемоизация функций-селекторов

Если Вы создаёте селектор непосредственно в теле компонента, при каждом рендеринге он получает новую ссылку на функцию, что может нарушить мемоизацию. Определяйте селекторы вне компонента или используйте useCallback.
// Outside component — stable reference
const selectName = s => s.user.name;

function Profile() {
  const name = useAppSelector(selectName);
  return <p>{name}</p>;
}

Производные селекторы

Составляйте селекторы, вызывая один селектор внутри другого. Производные селекторы вычисляют значения на основе базовых селекторов и не позволяют прикладной логике попадать в компоненты.
const selectFullName = s => s.user.firstName + ' ' + s.user.lastName;

Быстрая проверка

Почему функции-селекторы следует определять вне тела компонента при использовании с useContextSelector или useMemo?

Итоги

Селекторы извлекают часть состояния контекста и предотвращают повторные рендеринги при изменении несвязанных частей. Определяйте селекторы вне компонентов, чтобы их ссылки оставались стабильными. Используйте use-context-selector или Zustand для поддержки селекторов в готовых приложениях.

Далее

Следующий урок: **Когда не следует использовать контекст** — Вы научитесь распознавать ситуации, в которых передача свойств, композиция или менеджер состояния подходят лучше, чем Context.

Часто задаваемые вопросы

Урок «Паттерн селектора контекста» бесплатный?

Да — полный текст урока «Паттерн селектора контекста» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Паттерн селектора контекста»?

Реализуйте простой хук-селектор, который перерисовывает компонент только при изменении части контекста. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Паттерн селектора контекста»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Разделение контекстов для ограничения повторных рендерингов
  2. Мемоизация значений контекста с помощью useMemo
  3. Паттерн селектора контекста
  4. Когда не следует использовать контекст
← Назад к React Academy