useContext
Тема дорожной карты · React
useContext — это React-хук, подписывающий компонент на значение контекста, созданного с помощью React.createContext, и позволяющий глубоко вложенным компонентам читать разделяемое состояние без передачи пропсов через каждый промежуточный уровень дерева компонентов. Хук принимает объект контекста (значение, возвращённое createContext), и возвращает текущее значение контекста, предоставляемое ближайшим <Context.Provider> предком, автоматически перерендеривая потребляющий компонент при каждом изменении значения контекста. В TypeScript React-проектах createContext обычно получает типизированное начальное значение — createContext<AuthContextType | null>(null), — а useContext автоматически выводит тип возврата, обеспечивая типобезопасный доступ к объектам управления состоянием, токенам тем оформления или данным пользователей. useContext не является заменой специализированных библиотек управления состоянием, таких как zustand или Redux Toolkit, для высокочастотных обновлений, поскольку каждый потребитель контекста перерендеривается при изменении ссылки на объект значения контекста, что может вызывать проблемы производительности без аккуратного управления useMemo. Распространённый паттерн — инкапсуляция useContext внутри кастомного хука (например, useAuth, useTheme), который также выполняет проверку на null, — предоставляет более чистый API и предотвращает использование контекста вне его провайдера.
Как это работает
useContext позволяет пробросить данные через дерево компонентов, не передавая их через props на каждом уровне. createContext(default) возвращает пару {Provider, Consumer}; оборачиваете поддерево в <Provider value={...}>, любой потомок читает через useContext(Context). Context ререндерит всех consumers при изменении value по ссылке — <Provider value={{theme, setTheme}}> inline даёт ререндер каждый рендер (мемоизируйте объект).
Когда применять
Context — для по-настоящему глобальных, редко меняющихся данных: текущий пользователь, тема, локаль, feature flags. Пропустите его для high-frequency state (позиция мыши, ввод формы) — каждый consumer ререндерится на каждое изменение. Для app-state с селекторами и middleware — state-библиотека (Zustand, Redux Toolkit, Jotai). Композиция (передача children сверху) часто бьёт Context на 1-2 уровнях drilling.
Типичные ошибки
Ловушки useContext: весь app-state в одном Context (всё ререндерится на любое изменение); inline value-объект даёт ререндер каждый рендер; Context там, где state-библиотека работала бы лучше (нет devtools, нет time-travel, нет selector-level подписок); путаница Context с глобальным state — это всего лишь shortcut от prop drilling. Разделяйте Context по concern (UserContext, ThemeContext), чтобы ограничить blast radius.