React 的视图会随着数据的变化而变化
“组件间通信”的背后是一套环环相扣的 React 数据流解决方案
基于 Props 的单向数据流
组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即“props”)并返回用于描述页面展示内容的 React 元素。 —— Props
单向数据流
当前组件的 state 以 props 的形式流动时,只能流向组件树中比自己层级更低的组件
推荐使用 Props 解决的场景
父-子组件通信
父组件可以直接将 this.props 传入子组件,实现父-子间的通信
子-父组件通信
父组件传递给子组件的是一个绑定了自身上下文的函数,那么子组件在调用该函数时,就可以将想要的交给父组件的数据以函数入参的形式给出去
兄弟组件通信
为什么不推荐用 props 解决其它场景的需求
层层传递 props
- 层层传递的优点是非常简单,用已有知识就能解决
-
利用“发布-订阅”模式驱动数据流
优点:
监听事件的位置和触发事件的位置是不受限
class myEventEmitter {
constructor() {
this.eventMap = {};
}
on(type, handler) {
if(!(handler instanceof Function)) {
throw new Errow("Need input a Function");
}
if(!this.eventMap[type]) {
this.eventMap[type] = [];
}
this.eventMap[type].push(handler);
}
emit(type, params) {
if(this.eventMap[type]) {
this.eventMap[type].forEach((handler, index)=>{
handler(params);
})
}
}
off(type, handler) {
if(this.eventMap[type]) {
this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1);
}
}
}
Context API
React 官方提供的一种组件树全局通信的方式
在 React16.3 之前,Context API 由于存在各种局限性并不被 React 官方提倡使用,开发者更多的是把它作为一个概念来探讨 而从 v16.3.0 开始,React 对 Context API 进行了改进,新的 Context API 具备更强的可用性
createContext 可以传入一个 defaultValue 的参数,当 Consumer 没有找到 Provider 时使用
Provider 数据的提供者
<Provider value={title:this.state.title, content:this.state.content}>
<Title />
<Content />
</Provider>
Consumer 数据的消费者,可以读取 Provider 下发来的数据
<Consumer>
{value => <div>{value.title}</div>}
</Consumer>
过时 Context API 的问题
使用 childContextTypes、getChildContext、contextTypes
v16.3 前的 Context API 缺点是
- 代码不够优雅
很难韧带辨别出谁是 Provider、谁是 Consumer - 无法保证数据在生产者和消费者之间的及时同步
如果组件提供一个 Context 发生了变化,而中间父组件的 shouldComponentUpdate 返回 false,那么使用到该值的后代组件不会进行更新。使用了 Context 的组件则完全失控。所以基本上没有办法能够可靠的更新 Context。 —— React 官方
v16.3 之后的 Context API 解决了即便组件的 shouldComponentUpdate 返回 false,它仍然可以“穿透”组件继续向后代组件进行传播,进而确保了数据生产者和数据消费者之间数据的一致性。
Redux
随着应用的复杂度不断提升,需要维护的状态越来越多,组件间的关系也越来越难以处理的时候,需要请出 Redux 来帮忙
Redux 是 JavaSCript 状态容器,它提供可预测的状态管理
- 存储数据的公用仓库
如何帮助 React 管理数据
- store 是一个单一的数据源,而且是只读的
- action 是对变化的描述
- reducer 负责对变化进行分发和处理
在 Redux 的整个工作过程中,数据流是严格意向的
Redux 通过提供一个统一的状态容器,使得数据能够自由而有序地在任意组件之间穿梭