0Pricing
React Academy · Урок

Мемоизация значений контекста с помощью useMemo

Оборачивайте объекты значений контекста в useMemo, чтобы потребители не перерисовывались без необходимости.

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

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

В этом уроке Вы узнаете, почему объекты значений контекста необходимо мемоизировать с помощью useMemo и как правильно настроить зависимости, чтобы избежать ненужных повторных рендерингов.

Проблема ссылки на объект

Каждый раз, когда компонент-провайдер повторно отрисовывается, в качестве значения контекста создаётся новый литерал объекта `{ ... }`, даже если его содержимое не изменилось. Все потребители перерисовываются, потому что ссылка изменилась.
// Every render creates a new object!
<UserCtx.Provider value={{ user, logout }}>
  {children}
</UserCtx.Provider>

Исправление с помощью useMemo

Оберните значение контекста в useMemo, чтобы между рендерингами возвращалась та же ссылка на объект, если ни одна зависимость в массиве не изменилась.
const value = useMemo(
  () => ({ user, logout }),
  [user, logout]
);

<UserCtx.Provider value={value}>
  {children}
</UserCtx.Provider>

Тщательный выбор зависимостей

Включите в массив зависимостей каждое значение, используемое внутри useMemo. Отсутствующие зависимости приводят к устаревшим значениям. Включайте примитивные свойства, такие как строки и числа, а также стабильные ссылки, например функции, обёрнутые в useCallback.

Стабильные функции с useCallback

Ссылки на функции изменяются при каждом рендеринге. Оберните функции в useCallback перед включением их в значение контекста useMemo, чтобы предотвратить ненужные повторные рендеринги.
const logout = useCallback(() => {
  clearSession();
  setUser(null);
}, []);

const value = useMemo(() => ({ user, logout }), [user, logout]);

Когда мемоизация не нужна

Если компонент-провайдер никогда не перерисовывается, например находится в самом верху дерева и его родитель не изменяется, useMemo создаёт дополнительные затраты без пользы. Выполняйте мемоизацию только тогда, когда сам провайдер повторно отрисовывается.

Примитивные значения уже стабильны

Если значение контекста является примитивом, то есть строкой, числом или логическим значением, Вам НЕ нужен useMemo: примитивы сравниваются по значению, а не по ссылке. `value={isDark}` не вызовет дополнительных повторных рендерингов.
// No useMemo needed for primitives
<ThemeCtx.Provider value={isDark ? 'dark' : 'light'}>
  {children}
</ThemeCtx.Provider>

Профилирование эффекта мемоизации

Используйте профилировщик React DevTools, чтобы проверить, действительно ли оборачивание значения контекста в useMemo уменьшает количество повторных рендерингов. Запишите сеанс до и после изменений, чтобы увидеть разницу в количестве фиксаций.

Вложенные мемоизированные контексты

Если несколько контекстов вложены друг в друга, мемоизируйте каждый независимо. Изменения в одном контексте не повлияют на мемоизированное значение другого.

Шаблон компонента-провайдера

Инкапсулируйте контекст, состояние и мемоизацию внутри отдельного компонента-провайдера. Экспортируйте пользовательский хук для использования контекста. Это канонический шаблон для повторно используемых контекстов.
export function UserProvider({ children }) {
  const [user, setUser] = useState(null);
  const logout = useCallback(() => setUser(null), []);
  const value = useMemo(() => ({ user, logout }), [user, logout]);
  return <UserCtx.Provider value={value}>{children}</UserCtx.Provider>;
}

export const useUser = () => useContext(UserCtx);

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

Какова главная причина оборачивания объекта значения контекста в useMemo?

Итоги

Оборачивайте объекты значений контекста в useMemo с правильными зависимостями. Стабилизируйте значения функций с помощью useCallback. Примитивам мемоизация не нужна. Инкапсулируйте настройку контекста в компоненте-провайдере с пользовательским хуком.

Далее

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

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

Урок «Мемоизация значений контекста с помощью useMemo» бесплатный?

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

Чему я научусь в уроке «Мемоизация значений контекста с помощью useMemo»?

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

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

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

Сколько времени занимает урок «Мемоизация значений контекста с помощью useMemo»?

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

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

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

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

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