props 逐层透传(prop drilling)是深层组件拿数据的痛苦:中间组件被迫转发无关 props。Context 解决这个问题:createContext 创建上下文 → Provider 放在顶层提供数据 → 深处的组件用 useContext 直接订阅。主题、语言、当前用户这类「全局但低频变化」的数据是它的主场。
要注意性能:Context 值变化时所有订阅的组件都会重渲染(无论 memo 与否)。高频变化的状态(购物车、实时列表)应该上状态库(Redux/Zustand)或拆分多个 Context。拆分 Provider(ThemeProvider 与 UserProvider 分开)能让更新范围更小。
const { createContext, useContext, useState } = React;
// ① 创建上下文(给个默认值)
const ThemeCtx = createContext({ theme: 'light', toggle: () => {} });
// ② 顶层 Provider 提供数据
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeCtx.Provider value={{
theme,
toggle: () => setTheme(t => t === 'light' ? 'dark' : 'light'),
}}>
<Toolbar /> {/* 中间层无需转发任何 props */}
</ThemeCtx.Provider>
);
}
// ③ 深处订阅
function Toolbar() {
const { theme, toggle } = useContext(ThemeCtx);
return <button onClick={toggle}>当前主题:{theme}</button>;
}