PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Что такое useContext?

Хуки

useContext — хук для чтения значения из React Context: позволяет получать данные, положенные провайдером выше по дереву, без передачи через промежуточные props.

Использование

const ThemeContext = createContext('light');

const App = () => (
  <ThemeContext.Provider value="dark">
    <Toolbar />
  </ThemeContext.Provider>
);

const ThemedButton = () => {
  const theme = useContext(ThemeContext); // 'dark'
  return <button className={theme}>Ок</button>;
};

Хук возвращает value ближайшего провайдера выше по дереву; если провайдера нет — значение по умолчанию из createContext(default).

Какую проблему решает

Prop drilling — протаскивание данных через 5 промежуточных компонентов, которым они не нужны. Классические кандидаты в контекст: тема, локаль, текущий пользователь, инстанс роутера.

Как работает подписка

Компонент, вызвавший useContext, перерендеривается при каждом изменении value провайдера (сравнение по Object.is). Отсюда следует:

  • React.memo не защищает от обновления контекста;
  • инлайн-объект value={{ user, setUser }} — новая ссылка при каждом рендере провайдера, все потребители перерендерятся; лечится useMemo;
  • крупный «контекст всего приложения» — антипаттерн: любое изменение будит всех; лучше несколько узких контекстов.

Нюансы

  • useContext — это только транспорт, не стейт-менеджер: само состояние живёт в useState/useReducer у провайдера.
  • Частые обновления (ввод текста, координаты мыши) в контексте — источник тормозов; для такого лучше стор с точечными подписками.

Коротко для собеседования

useContext читает значение ближайшего провайдера контекста, избавляя от prop drilling. Все потребители перерендериваются при изменении value, поэтому value мемоизируют, а контексты разделяют по частоте изменений. Контекст — транспорт данных, а не замена стейт-менеджера для часто меняющегося состояния.

Другие вопросы раздела