Что такое 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 мемоизируют, а контексты разделяют по частоте изменений. Контекст — транспорт данных, а не замена стейт-менеджера для часто меняющегося состояния.