-
上下文处理组件跨层级通信:
- 使用上下文中的
Consumer
- 使用
Hook
api useContext
- 在
class
类组件中,将创建的上下文赋值给一个静态属性 contextType
- 上下文处理的组件跨层级通信主要是由最外层组件向内层组件传递数据,像Vue中的
inject
,不需要再层层传递props
- 先初始化一个
child
组件,然后去实现跨组件层级和Child
通信
// src/components/ContextTest.js
import React from 'react';
function Child () {
return (
<div>Child</div>
)
}
export default function ContextTest () {
return (
<div>
<Child></Child>
</div>
)
}
- 使用上下文之前要先创建上下文,然后从上下文中解构出
Provider
,再用 Provider
将接收数据的组件包裹起来,然后通过 Provider
的 value
属性就可以实现跨组件层级传递数据了
// src/components/ContextTest.js
import React from 'react';
// 创建上下文
// 这个功能概念可理解为vue中的provide和inject
const MyContext = React.createContext()
const {Provider} = MyContext
function Child () {
return (
<div>Child</div>
)
}
export default function ContextTest () {
return (
<div>
{/* 将Child组件用Provider包裹起来,通过Provider的value属性就可以传值了 */}
<Provider value={{name: 'asher'}}>
<Child></Child>
</Provider>
</div>
)
}
- 实现了跨组件传值,那就要再继续解决跨组件接收值,有一种方式是使用上下文中的
Consumer
,所有需要接收数据的组件用 Consumer
包裹起来,然后 Consumer
能拿到 Provider
传递出来的值, Consumer
再通过函数形式传递出去,Consumer
与 Provider
之间可以有很多层组件间隔
// src/components/ContextTest.js
import React from 'react';
// 创建上下文
// 这个功能概念可理解为vue中的provide和inject
const MyContext = React.createContext()
// 解构出Provider、Consumer
const {Provider, Consumer} = MyContext
// Child组件中通过props获取
function Child (props) {
return (
<div>Child: {props.name}</div>
)
}
export default function ContextTest () {
return (
<div>
{/* 将Child组件用Provider包裹起来,通过Provider的value属性就可以传值了 */}
<Provider value={{name: 'asher'}}>
{/* 需要接收值的组件要被包裹在Consumer内 */}
{/* Consumer内部执行一个方法,拿到传递的值传给Child,有点类似组件复合 */}
<Consumer>
{val => <Child {...val}></Child>}
</Consumer>
</Provider>
</div>
)
}
- 接收值的另一种方式是使用
Hook
,使用 Hook
api useContext
,我们改写下上面的代码让代码看起来清晰一点,不同的接收值方法分别用不同的组件来展示,同时引入下 useContext
// src/components/ContextTest.js
import React, {useContext} from 'react';
const MyContext = React.createContext()
const {Provider, Consumer} = MyContext
// 跨组件通信方法1:利用<consumer></consumer>组件
function Child1 (props) {
return (
<div>child1: {props.name}</div>
)
}
// 跨组件通信2:使用hook
function Child2 () {
// 把创建的上下文传递给useContext
// 直接从上下文中获取属性
const ctx = useContext(MyContext)
return (
<div>child2: {ctx.name}</div>
)
}
export default function ContextTest () {
return (
<div>
<Provider value={{name: 'asher'}}>
{/* 跨组件通信方法1 */}
<Consumer>
{val => <Child1 {...val}></Child1>}
</Consumer>
{/* 跨组件通信方法2 */}
<Child2></Child2>
</Provider>
</div>
)
}
- 接收值的第3种方式是针对于
class
类组件的,使用类组件中的静态属性 contextType
// src/components/ContextTest.js
import React, {useContext} from 'react';
const MyContext = React.createContext()
const {Provider, Consumer} = MyContext
// 跨组件通信方法1:利用<consumer></consumer>组件
function Child1 (props) {
return (
<div>child1: {props.name}</div>
)
}
// 跨组件通信2:使用hook
function Child2 () {
// 把创建的上下文传递给useContext
// 直接从上下文中获取属性
const ctx = useContext(MyContext)
return (
<div>child2: {ctx.name}</div>
)
}
// 跨组件通信3:class指定静态contextType
class Child3 extends React.Component {
// 声明一个静态属性
// 通过固定变量名this.context获取
static contextType = MyContext
render () {
return (
<div>Child3: {this.context.name}</div>
)
}
}
export default function ContextTest () {
return (
<div>
<Provider value={{name: 'asher'}}>
{/* 跨组件通信方法1 */}
<Consumer>
{val => <Child1 {...val}></Child1>}
</Consumer>
{/* 跨组件通信方法2 */}
<Child2></Child2>
{/* 跨组件通信方法3 */}
<Child3></Child3>
</Provider>
</div>
)
}
网友评论