组建通信在我的简单理解可以这么觉得:就是组件与组件之间的属性传递。像我们传统的父子组件的state和props的属性传递一样,但是在我们的代码量越来越多的情况下,组件之间的层层嵌套。如果单纯的还是使用state,props进行层层传递,那么很有可能就会遗失掉一些属性,更不利于我们后期的代码维护,所以react 官方就提供了这么一个context上下文方法。
Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性。
我先用一个简单的例子给大家展示一下手动传递属性的痛苦
import React, { Component } from 'react';
//定义数据源,进行属性传递
let store = {
name:'数据源仓库'
}
class InfoComp extends Component {
render() {
return (
<div>这里想要访问到store里面的name属性:{this.props.name}</div>
);
}
}
function CenterComp (props) {
return (
<div>
<InfoComp {...props} ></InfoComp>
</div>
)
}
class Context extends Component {
render() {
return (
<div>
<h2>React组建通信 connext 学习</h2>
<CenterComp name={store.name} />
</div>
);
}
}
export default Context;
上面这段代码,也只是爷父孙三个组件的嵌套,可能有同学会觉得还行,但如果是再来几个孙子的儿子,孙子的孙子,那我觉得大家可能就会崩溃了吧,所以这时候就很能体现context的重要性了。
context有两个角色
- Provider 数据提供(生产者:生产数据,提供数据)
- Consumer 数据读取 (消费者:获取数据,使用数据)
让我们来看看用context改造上面的例子
import React, { Component } from 'react';
//定义数据源,进行属性传递
let store = {
name:'数据源仓库'
}
//第一步:创建Context对象
const NewContext = React.createContext()
//第二步:从Context对象中获取 提供数据的Provider 和 读取数据的Consumer
const { Provider ,Consumer} = NewContext
class InfoComp extends Component {
render() {
return (
//第四步:使用Consumer使用从Provider中传递过来的store, 利用箭头函数传递给需要数据的位置。
<Consumer>
{
store=>{
// 通过store.name就能拿到想要的属性name
return <div>这里想要访问到store里面的name属性:{store.name}</div>
}
}
</Consumer>
);
}
}
function CenterComp (props) {
return (
<div>
<InfoComp></InfoComp>
</div>
)
}
class Context extends Component {
render() {
return (
<div>
<h2>React组建通信 connext 学习</h2>
{/* 第三步:将store从Provider传递出去 ,让被包裹的子组件都能拿到数据*/}
<Provider value={store}>
<CenterComp/>
</Provider>
</div>
);
}
}
export default Context;
这是效果图:
其中最需要注意的地方就是两点:
- Provider 千万不能忘记传递数据,不然Consumer是拿不到数据的
- Consumer 使用时 一定要先拿出我们想要的从Provider拿到的数据store,使用回调函数的方式,让里面的代码块拿到想要的数据
我觉得学好理解了context上下文这块内容,对之后学习redux 是十分有用的,大家可以细细琢磨下