0Pricing
React Academy · Урок

Разделение контекстов для ограничения повторных рендерингов

Разделяйте часто изменяющиеся значения и стабильные значения, помещая их в разные контексты.

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

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

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

Проблема повторного рендеринга в контексте

Каждый компонент, вызывающий useContext(MyCtx), повторно отрисовывается при изменении ANY части значения контекста — даже если используемая им часть не изменилась. Один большой контекст может вызывать множество ненужных повторных рендерингов.

Разделение по частоте обновлений

Отделяйте значения, которые часто изменяются, от значений, которые меняются редко. Поместите каждую группу в собственный контекст. Потребители подписываются только на нужный им контекст.
const ThemeCtx = createContext('light');
const UserCtx = createContext(null);
// theme changes rarely; user changes on login/logout — same frequency is fine
// but notifCount changes every second — split it out!

Разделение контекстов данных и диспетчеризации

Распространённый шаблон — разделить один контекст для данных состояния, который повторно отрисовывается при каждом изменении, и другой для функций диспетчеризации и установки, которые стабильны и не вызывают повторный рендеринг потребителей. Потребители, использующие только диспетчеризацию, не перерисовываются при изменении данных.
const CountCtx = createContext(0);
const SetCountCtx = createContext(() => {});

function Provider({ children }) {
  const [count, setCount] = useState(0);
  return (
    <CountCtx.Provider value={count}>
      <SetCountCtx.Provider value={setCount}>
        {children}
      </SetCountCtx.Provider>
    </CountCtx.Provider>
  );
}

Мемоизация контекста диспетчеризации

Сеттеры из useState стабильны: при каждом рендеринге они имеют ту же ссылку, поэтому значение контекста диспетчеризации не изменяется. Но если Вы вычисляете объект actions, оберните его в useMemo.
const actions = useMemo(() => ({
  increment: () => setCount(c => c + 1),
  reset: () => setCount(0),
}), []); // stable — empty deps

Вложенные провайдеры

Вложите несколько провайдеров в дерево компонентов. Потребители импортируют и используют только нужный им конкретный контекст, сохраняя подписки узкими.
function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <NotificationsProvider>
          <Router />
        </NotificationsProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

Профилирование перед разделением

Всегда выполняйте профилирование с помощью React DevTools перед разделением контекстов. Ненужные повторные рендеринги являются проблемой только в том случае, если они затратны. Не усложняйте контексты без необходимости, если они быстро перерисовываются.

Компромиссы при разделении контекстов

Чем больше контекстов, тем больше провайдеров в дереве компонентов. Это увеличивает когнитивную нагрузку. Разделяйте контексты только тогда, когда профилирование показывает проблему производительности, а не заранее.

Сочетание с React.memo

Даже при использовании одного контекста оборачивание дорогих дочерних компонентов в React.memo означает, что они повторно отрисовываются только при изменении их свойств, а не при изменении контекста. Это может быть более простой альтернативой разделению.
const ExpensiveChild = React.memo(function({ label }) {
  return <div>{label}</div>;
}); // won't re-render on context change if label hasn't changed

useReducer и контекст

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

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

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

Итоги

Разделяйте контексты по частоте обновлений: часто изменяющееся состояние помещайте в один контекст, а стабильные функции диспетчеризации и установки — в другой. Сначала выполняйте профилирование, разделяйте контексты только при необходимости и рассматривайте React.memo как более простой вариант.

Далее

Следующий урок: **Мемоизация значений контекста с помощью useMemo** — Вы обернёте объекты значений контекста в useMemo, чтобы потребители не перерисовывались при неизменных данных.

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

Урок «Разделение контекстов для ограничения повторных рендерингов» бесплатный?

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

Чему я научусь в уроке «Разделение контекстов для ограничения повторных рендерингов»?

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

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

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

Сколько времени занимает урок «Разделение контекстов для ограничения повторных рендерингов»?

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

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

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

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

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