react的Context 跨层传值、优缺点、适用场景

React 的 Context(上下文)主要解决 跨层级组件传值(Props Drilling) 问题,即:父组件的数据需要经过很多层组件,最终传给深层子组件。


1. 什么是 Context

没有 Context:

javascript 复制代码
function App() {
  const theme = 'dark';

  return <Parent theme={theme} />;
}

function Parent({ theme }) {
  return <Child theme={theme} />;
}

function Child({ theme }) {
  return <GrandChild theme={theme} />;
}

function GrandChild({ theme }) {
  return <div>{theme}</div>;
}

数据:

复制代码
App → Parent → Child → GrandChild

即使 Parent 和 Child 不使用 theme,也必须传。

这种叫:

复制代码
Props Drilling(属性穿透)

Context 用于解决这个问题。


2. Context 使用步骤(跨层传值)

React Context 核心 API:

scss 复制代码
createContext()
Provider
useContext()

第一步:创建 Context

创建:

javascript 复制代码
// ThemeContext.js

import { createContext } from "react";

export const ThemeContext = createContext();

默认值:

scss 复制代码
createContext("light");

如果 Provider 没包裹,会取默认值。


第二步:Provider 提供数据

根组件:

javascript 复制代码
import { ThemeContext } from "./ThemeContext";

function App() {

  const theme = "dark";

  return (
    <ThemeContext.Provider value={theme}>
      <Parent />
    </ThemeContext.Provider>
  );
}

Provider:

复制代码
提供共享数据

value:

复制代码
所有子组件可访问

第三步:子组件获取

深层组件:

javascript 复制代码
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";

function GrandChild() {

    const theme =
      useContext(ThemeContext);

    return <div>{theme}</div>;
}

输出:

复制代码
dark

即:

scss 复制代码
App
 ↓
Provider(value=dark)
 ↓
Parent
 ↓
Child
 ↓
GrandChild
 ↓
useContext()

直接拿值,不需要层层传。


完整例子

javascript 复制代码
import React,
{
 createContext,
 useContext,
 useState
}
from "react";

const UserContext =
createContext();

function App(){

 const [user,setUser]=
 useState("Tom");

 return(

<UserContext.Provider
value={{user,setUser}}
>

<Home/>

</UserContext.Provider>

 )
}

function Home(){

 return <Profile/>

}

function Profile(){

 const {user,setUser}
 =
 useContext(UserContext);

 return(

<>
<p>{user}</p>

<button
onClick={()=>
setUser("Jerry")
}
>

修改

</button>

</>

 )

}

结果:

点击按钮:

复制代码
Tom → Jerry

所有使用 Context 的组件都会更新。


3. Context 优点

(1)解决 Props Drilling

以前:

css 复制代码
App
↓
A
↓
B
↓
C
↓
D

需要:

ini 复制代码
<A user={user}/>
<B user={user}/>
...

Context:

scss 复制代码
useContext(UserContext)

直接取。

优势最大。


(2)全局共享状态

适合:

复制代码
用户信息
主题
权限
语言
Token
购物车

例如:

复制代码
theme
locale
loginUser

多个页面共用。


(3)代码更简洁

减少:

复制代码
props.xxx.xxx

改成:

scss 复制代码
useContext()

(4)避免层层维护

修改组件层级:

以前:

css 复制代码
App→A→B→C

变:

css 复制代码
App→X→A→B→C

props 全改。

Context 不需要。


4. Context 缺点

虽然方便,但不是状态管理库。


缺点1:性能问题(最大问题)

Context 数据变化:

ini 复制代码
value={{
 user,
 setUser
}}

user 改变:

复制代码
所有 useContext 的组件重新渲染

即使组件没用到变化的数据。

例如:

css 复制代码
UserContext

├── Header
├── Menu
├── Profile
└── Footer

修改:

复制代码
user.name

可能:

css 复制代码
Header 重渲染
Menu 重渲染
Footer 重渲染

性能下降。


优化:

scss 复制代码
const value =
useMemo(()=>({
 user,
 setUser
}),[user])

或拆多个 Context。



缺点2:不适合复杂状态

复杂业务:

复制代码
异步请求
缓存
分页
撤销
loading

Context 管理会混乱。

这时推荐:

  • Redux Toolkit
  • Zustand
  • MobX

缺点3:调试困难

Redux:

能看:

perl 复制代码
dispatch
state变化
时间旅行

Context:

没有。


缺点4:Provider 嵌套地狱

容易出现:

xml 复制代码
<AuthProvider>

<ThemeProvider>

<UserProvider>

<CartProvider>

<App/>

</CartProvider>

</UserProvider>

</ThemeProvider>

</AuthProvider>

可读性下降。


5. Context 适用场景

适合(推荐):

① 登录用户信息

复制代码
userInfo
token
role

② 主题切换

暗黑模式:

bash 复制代码
dark/light

最经典。


③ 多语言

复制代码
zh
en
jp

④ 权限控制

复制代码
isAdmin
permission

⑤ 全局配置

复制代码
API地址
系统配置

6. 不适合场景

不推荐:

大型复杂状态

例如:

复制代码
订单系统
即时聊天
性能平台
工作流系统

像你做的云鉴性能平台:

复制代码
性能查询
分页
筛选
缓存
异步请求
报告状态

更适合:

  • Redux Toolkit
  • Zustand
  • React Query + Context
  • MobX

而不是纯 Context。


7. Context 与 Redux 区别

对比 Context Redux
学习成本 低 高
跨层传值 √ √
状态管理 一般 强
性能优化 较差 好
调试 差 强
异步 弱 强
大项目 不推荐 推荐

8. 一句话总结

Context 本质:

复制代码
跨组件共享数据机制

适合:

复制代码
主题
登录
权限
语言
配置

不适合:

复制代码
复杂全局状态管理

复杂项目优先考虑:

复制代码
Redux Toolkit
Zustand
React Query
相关推荐
去伪存真4 分钟前
从乱码到高精度检索:探矿业务中 TXT、Word、PDF 与网页的 RAG 清洗之道
前端·agent
两个西柚呀13 分钟前
JS事件总结
前端·javascript·css
小狼1545416 分钟前
拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手
java·前端·javascript
ss27339 分钟前
AI全栈实战 | 2.2-02 React 思维模型:数据不可变 vs Vue 数据可变,两种哲学把复杂度推给谁
前端·vue.js·react.js
天衍四九-42 分钟前
Docker Compose企业实战系列(三):Vue/React前端项目容器化完整部署
前端·vue.js·docker
Rosanci1 小时前
从零到合入主线:我的 DeepSeek Harness 开源贡献实战手记
开发语言·前端·开源
用户960819842231 小时前
多周期联看时十字光标对不齐:前端排查「时间桶」的三步清单
前端
Data analyse4561 小时前
数据合规的敏感数据怎么识别?
前端·人工智能·数据分析
陪我一起学编程2 小时前
vue3笔记
前端·webpack·vue3·vite·脚手架·vue3笔记·组件式
object not found2 小时前
WooCommerce 接入 KPay 后订单完成页不显示订单信息:returnUrl 动态参数问题解决
前端·wordpress·独立站支付