react context 使用方法 + hooks版本 + class类版本( 不比react-redux香吗? )
最近写了一个组件,发现别人传递参数后,组件逐层传递数据(props)太麻烦了,而且我也不需要改变根组件的状态值,也不想使用redux,
突然发现 context 很适合使用( 跨层级传递数据 )
今天就介绍下context(执行的上下文)
我们和网上的案例不一样,我们分文件写代码,写在不同的js里面(更符合实际,网上的案例10个9复制),下面有实例(hooks版本的)
使用步骤
1、使用 React.CreateContext() 创建context
2、React.Provider标签包裹想要分享组件的父组件,value传递你要分享的数据(可以写成对象形式),例:value:{{ name:"张三",changeNameHandle: changeNameHandle }}
3、子代组件使用分享的数据:React.Consumer包裹需要使用数据的组件,然后使用 { value => { return ( 你要展示的结构 ) } },包裹你要展示的结构,下方Children.js有红色标记
效果

孙子组件想用劳资组件的数据
hooks版本
1、context.js(建立一个context文件,这样声明的context就可以随时引用)
1 import React from "react"; 2 const MyContext = React.createContext(); 3 // 常见一个context,并把 Provider 和 Consumer 暴露出去 4 export const { Provider,Consumer } = MyContext;
2、Labor.js
1 import React, { useState } from "react"; 2 // 引入声明的context 3 import { Provider } from './context'; 4 import Far from './Far'; 5 6 const Labor = () => { 7 const [value,changeValue] = useState(1); //随便声明一个变量 8 9 // 声明的一个函数,可以在这个函数里改变useState声明的变量操作 10 const handleChange = (data) => { 11 // 例如孙子组件点击一下 value + data 12 changeValue(value + data) 13 } 14 15 return ( 16 <Provider 17 value={{ value:value,handleChange:handleChange }} 18 > 19 <div style={{ backgroundColor:"#6fe6df",padding:35 }}> 20 劳资组件 21 <Far /> 22 23 </div> 24 </Provider> 25 ) 26 } 27 28 export default Labor;
3、Far.js
import React from "react"; import Children from './Children'; const Far = () => { return ( <div style={{ backgroundColor:"#f54110",padding:50 }}> 父亲组件 <Children /> </div> ) } export default Far ;
4、Children.js
import React from "react"; import { Button } from 'antd' // 引入consumer import { Consumer } from './context'; const Children = () => { return ( <Consumer> { value => { return ( <div style={{ backgroundColor:"#65f781",padding:20 }}> 孙子组件{value.value} <Button type="primary" //调用劳资组件传递过来的方法 onClick={()=>value.handleChange(1)} > 尝试改变 </Button> </div> ) } } </Consumer> ) } export default Children ;
其实很简单:
Provider包裹父组件,并把需要分享的数据给到Provider标签中value属性,
后面的子代谁想使用分享的数据,就用Consumer标签包裹,并用 { value => { return ( 原本组件的结构 ) } },使用分享的数据就在里面 value.属性
class类的组件使用 context 会有点不一样
1、MyContext.js
1 import React from "react"; 2 export const MyContext = React.createContext();
2、Labor.js
1 import React, { useState } from "react";
2 // 引入声明的context
3 import { MyContext } from './context';
4 import Far from './Far';
5
6 const Labor = () => {
7 const [value,changeValue] = useState(1); //随便声明一个变量
8
9 // 声明的一个函数,可以在这个函数里改变useState声明的变量操作
10 const handleChange = (data) => {
11 // 例如孙子组件点击一下 value + data
12 changeValue(value + data)
13 }
14
15 return (
16 <MyContext.Provider
17 value={{ value:value,handleChange:handleChange }}
18 >
19 <div style={{ backgroundColor:"#6fe6df",padding:35 }}>
20 劳资组件
21 <Far />
22
23 </div>
24 </MyContext.Provider >
25 )
26 }
27
28 export default Labor;
3、Far.js
import React from "react"; import Children from './Children'; const Far = () => { return ( <div style={{ backgroundColor:"#f54110",padding:50 }}> 父亲组件 <Children /> </div> ) } export default Far ;
4、Children.js
import React, { Component } from 'react';
import { Button } from 'antd';
import { MyContext } from '../../../context';
export default class Children extends Component {
static contextType = MyContext;
render() {
return (
<div style={{ backgroundColor:"#65f781",padding:20 }}>
孙子组件{this.context.value}
<Button
type="primary"
onClick={()=>this.context.handleChange(1)}
>尝试改变</Button>
</div>
)
}
}
或者
import React, { Component } from 'react';
import { Button } from 'antd';
import { MyContext } from '../../../context';
export default class Children extends Component {
render() {
return (
<MyContext.Consumer>
{
value => {
return (
<div style={{ backgroundColor:"#65f781",padding:20 }}>
孙子组件{value.value}
<Button
type="primary"
onClick={()=>value.handleChange(1)}
>尝试改变</Button>
</div>
)
}
}
</MyContext.Consumer>
)
}
}
Redux和Context对比
如果项目体量较小,只是需要一个公共的store存储state,而不讲究使用action来管理state,那context完全可以胜任。反之,则是redux的优点。
context的缺点
- React 新特性 context 在大型数据应用的前提下,并不会减少模版代码。而其 Provider 和 Consumer 的一一对应特性,即 Provider 和 Consumer 必须来自同一次 React.createContext 调用(可以用 hack 方式解决此“局限”)
- 因为没有了action,state的值都是被直接修改,state的数据安全性不及redux。
- 不能使用redux的中间件,比如thunk/saga,在一些异步的情况需要自己来处理。

浙公网安备 33010602011771号