React中的useContext
文章类型:React
发布者:hp
发布时间:2025-10-16
允许你在组件中订阅React的Context(上下文)而不需要使用传统的Context.Consumer组件
简单来说,就是解决props信息传递给子组件层层传递的问题,允许Context父组件向其下层无论多深的任何组件提供信息
第一步创建=>(createContext(defaultValue))
第二步使用=>(<MyContext.Provider value={someValue}>)
第三步消费=>(useContext(MyContext) )
//引入Context
import { createContext,useContext } from 'react'
// 1. 创建 Context(默认值为 '3')
const NameContext = React.createContext('3');
// 2. 父组件:提供 Context 值
function Parent() {
return (
<NameContext.Provider value="1"> {/* 这里提供值 "1" */}
<Child />
</NameContext.Provider>
);
}
// 3. 中间组件
function Child() {
return <Son />;
}
// 4. 孙组件:消费 Context
function Son() {
const name = useContext(NameContext); // 获取值
return <div>名字: {name}</div>; // 输出 "名字: 1"
}
1:忘记使用Provider=>必须确保树中有对应的Provider
2:Provider得value没有变化但是组件重新渲染=>只要父组件有变化,那么即使value没变化,也会重新渲染
3:多层Provider嵌套时值获取=>会返回离它最近的Provider值
4:在类组件使用情况=>useContext只能在函数组件使用,类组件使用需要Context.Consumer或static contextType
1:拆分Context,不要把所有状态放在一个Context中,避免所有消费组件重新渲染
// 好的做法 - 拆分Context
<UserContext.Provider value={user}>
<UserDispatchContext.Provider value={setUser}>
<ProfileContext.Provider value={profile}>
{/* ... */}
</ProfileContext.Provider>
</UserDispatchContext.Provider>
</UserContext.Provider>
2:使用userMeno记忆化value,避免重新渲染
const user = useMemo(() => ({ name: 'John', age: 30 }), []);
return (
<UserContext.Provider value={user}>
{/* ... */}
</UserContext.Provider>
);
3:使用React.memo将消费组件记忆化,避免子组件不必要渲染
const ThemedButton = React.memo(function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#EEE' }}>按钮</button>;
});
1:主题切换
2:用户认证
1:React Context提供了一种在组件树中共享数据的方式,而不必显式地通过组件树的每一层传递props。
2:它主要解决了"prop drilling"(属性钻取)问题,即当需要在多层嵌套组件中传递数据时,中间层组件即使不需要这些数据,也必须接收并向下传递这些props
Context:
内置于React,无需额外依赖
适合共享简单的、不频繁变化的数据
没有中间件、时间旅行调试等高级功能
当Provider的值变化时,所有消费组件都会重新渲染
Redux:
需要单独安装
适合管理复杂的应用状态
提供中间件支持、时间旅行调试等功能
使用选择器精确控制组件的重新渲染
Context:
共享主题、用户认证等简单的全局状态
数据更新不频繁
应用规模较小
Redux:
应用状态复杂且更新频繁
需要中间件处理异步逻辑
使用Context.Consumer
class ThemedButton extends React.Component {
render() {
return (
<ThemeContext.Consumer>
{theme => (
<button style={{ background: theme }}>按钮</button>
)}
</ThemeContext.Consumer>
);
}
}
使用static contextType
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
return <button style={{ background: theme }}>按钮</button>;
}
}
function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme必须在ThemeProvider内使用');
}
return context;
}
// 使用
function ThemedButton() {
const { theme, toggleTheme } = useTheme();
// ...
}
暂无评论,快来发表第一条评论吧~