文章目录
前言
之前的文章我们介绍了在react中使用props实现组件通信,比如父子,祖孙通信,但是使用props一层层传递的时候还是很麻烦的,那么今天这篇文章就来介绍新的用法——使用Context实现组建通信
Context
在react官方文档中是这样解释的:Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。此处附上传送门Context-react
Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。下面一起来看看如何使用Context实现组件通信
祖孙传值
最外层组件(祖组件):
- 引入父组件(hello.js),引入context中的MainContext
- 使用<MainContext.Provider value={this.state.arr}>提供服务进行传值,value就是要传的值
import React, {
Component } from 'react'
import Hello from './hello'
import MainContext from './context'
export class Main extends Component {
state = {
// arr: [1, 2, 3],
arr: 'hello',
obj: {
name: 'chaochao'}
}
render() {
return (
<div>
<MainContext.Provider value={
this.state.arr}>
Main Page
<Hello/>
</MainContext.Provider>
</div>
)
}
}
export default Main
孙组件:
上面祖组件已经使用MainContext.Provider进行传值了,那么在这里就不需要一层层传值,在孙组件中可以直接使用MainContext.Consumer组件进行接收
1.从context.js中引入MainContext
2.使用MainContext.Consumer进行取值
这样就可以成功在孙组件中拿到祖组件的值
import React, {
Component } from 'react'
import MainContext from './context'
export class World extends Component {
render() {
return (
<MainContext.Consumer>
{
context => {
return (
<div>World Page --- {
context}</div
)
}
}
</MainContext.Consumer>
)
}
}
export default World
除了使用MainContext.Consumer进行取值,这里还有一种方法:
可以使用static contextType = MainContext 或者 Hello.contextType = MainContext,这样就能直接是使用this.context获取到传入的值
export class Hello extends Component {
// static contextType = MainContext
render() {
return (
<div>Hello Page==={
this.context}
<World />
</div>
)
}
}
Hello.contextType = MainContext // 等同于第二行代码的作用
嵌套传值
上面的例子是祖组件传值给孙组件组,孙组件中使用了MainContext.Consumer接收值,但是如果孙组件还要接收别的组件传过来的值,那么我们就要嵌套MainContext.Consumer进行接收
这里来举例说明一下:
新建一个userContext.js:
import React from 'react'
const UserContext = React.createContext()
export default UserContext
在祖组件中进行嵌套传值:
- 同时引入两个context的文件
- 注意看MainContext.Provider和UserContext.Provider进行嵌套传值
import React, {
Component } from 'react'
import Hello from './hello'
import MainContext from './context'
import UserContext from './userContext'
export class Main extends Component {
state = {
// arr: [1, 2, 3],
arr: 'hello',
obj: {
name: 'chaochao'}
}
render() {
return (
<div>
<MainContext.Provider value={
this.state.arr}>
<UserContext.Provider value={
this.state.obj}>
Main Page
<Hello/>
</UserContext.Provider>
</MainContext.Provider>
</div>
)
}
}
export default Main
孙组件中:
1.也是要同时引入两个context
2. 接收值也需要进行嵌套,注意观察写法
这样就能就收到两个不同的值
import React, {
Component } from 'react'
import MainContext from './context'
import UserContext from './userContext'
export class World extends Component {
render() {
return (
// 函数式组件中比较推荐使用Consumer进行取值消费
<MainContext.Consumer>
{
context => {
return <UserContext.Consumer>
{
user => {
console.log(context, user)
return (
<div>World Page --- {
context} --- {
user.name}</div>
)
}}
</UserContext.Consumer>
}}
</MainContext.Consumer>
)
}
}
export default World
Context使用步骤总结
还是和之前一样,通过小案例来实现用法,祖组件传值给孙组件
新建context.js文件,用来使用context
context.js中内容:
import React from 'react'
// 创建一个 Context 对象,组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。
const MainContext = React.createContext('这里面可以设置默认值')
export default MainContext
// 传值使用Provider接收value属性,传递给消费组件
<MainContext.Provider value={
/* 某个值 */}>
接收值的两种方法:
- 使用Context.Consumer(多用于函数式组件)
<MainContext.Consumer>
{
value => /* 基于 context 值进行渲染*/}
</MainContext.Consumer>
- 用Class.contextType挂载在class上,然后使用 this.context 来消费最近 Context 上的那个值。可以在任何生命周期中访问到它,包括 render 函数中。(多用于类组件)
static contextType = MainContext
// 或者
Hello.contextType = MainContext
// 就可以直接用this.context访问了
本篇文章就到这里结束啦,如果对你有帮助的话,点赞关注支持一下谢谢~
后续还会给大家继续带来优质的前端内容~ 持续更新!!!