image.png
React 的视图会随着数据的变化而变化
“组件间通信”的背后是一套环环相扣的 React 数据流解决方案

基于 Props 的单向数据流

组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即“props”)并返回用于描述页面展示内容的 React 元素。 —— Props

单向数据流

当前组件的 state 以 props 的形式流动时,只能流向组件树中比自己层级更低的组件

推荐使用 Props 解决的场景

父-子组件通信

父组件可以直接将 this.props 传入子组件,实现父-子间的通信

子-父组件通信

父组件传递给子组件的是一个绑定了自身上下文的函数,那么子组件在调用该函数时,就可以将想要的交给父组件的数据以函数入参的形式给出去

兄弟组件通信

image.png

为什么不推荐用 props 解决其它场景的需求

层层传递 props
image.png

  • 层层传递的优点是非常简单,用已有知识就能解决
  • 问题是会浪费很多代码,非常烦琐

    利用“发布-订阅”模式驱动数据流

    优点:

  • 监听事件的位置和触发事件的位置是不受限

    1. class myEventEmitter {
    2. constructor() {
    3. this.eventMap = {};
    4. }
    5. on(type, handler) {
    6. if(!(handler instanceof Function)) {
    7. throw new Errow("Need input a Function");
    8. }
    9. if(!this.eventMap[type]) {
    10. this.eventMap[type] = [];
    11. }
    12. this.eventMap[type].push(handler);
    13. }
    14. emit(type, params) {
    15. if(this.eventMap[type]) {
    16. this.eventMap[type].forEach((handler, index)=>{
    17. handler(params);
    18. })
    19. }
    20. }
    21. off(type, handler) {
    22. if(this.eventMap[type]) {
    23. this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1);
    24. }
    25. }
    26. }

    image.png

    Context API

    React 官方提供的一种组件树全局通信的方式

    在 React16.3 之前,Context API 由于存在各种局限性并不被 React 官方提倡使用,开发者更多的是把它作为一个概念来探讨 而从 v16.3.0 开始,React 对 Context API 进行了改进,新的 Context API 具备更强的可用性

image.png
image.png
createContext 可以传入一个 defaultValue 的参数,当 Consumer 没有找到 Provider 时使用
image.png
Provider 数据的提供者

  1. <Provider value={title:this.state.title, content:this.state.content}>
  2. <Title />
  3. <Content />
  4. </Provider>

Consumer 数据的消费者,可以读取 Provider 下发来的数据

  1. <Consumer>
  2. {value => <div>{value.title}</div>}
  3. </Consumer>

过时 Context API 的问题
image.png
使用 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 状态容器,它提供可预测的状态管理

  • 存储数据的公用仓库

image.png

如何帮助 React 管理数据

  • store 是一个单一的数据源,而且是只读的
  • action 是对变化的描述
  • reducer 负责对变化进行分发和处理

image.png
在 Redux 的整个工作过程中,数据流是严格意向的
Redux 通过提供一个统一的状态容器,使得数据能够自由而有序地在任意组件之间穿梭

从编码角度理解 Redux 工作流

image.png

image.png
image.png
image.png
image.png
image.png