深入Redux

简述

快速理解redux中,我简单的介绍了redux的基础内容,本篇文章中,我们将再度深入redux。

redux解决的问题

  • 数据和函数的层层传递
  • 多个组件同时修改某全局变量

一、react数据流

  • 众所周知,react的单向数据流是这样的,父组件可以向子组件传递数据
    react单项数据流
    我们通常用过状态提升将数据存于高阶函数中,使我们的子组件尽可能的更"纯",更好的实现代码复用。
  • 可能在页面结构简单的小型项目中我们还没觉得有什么不妥,但是倘若在页面结构稍复杂的项目中,就会变成这样
    react单项数据流
    D组件中的数据存于Container中,要通过Container -> Content -> B -> D才能到达D组件。
    当然,这对我们聪明有能干的开发者们并不算什么,耗些时间也能刚出来。
  • Then,这种页面,你还能搞得定吗?
    react单项数据流
    就算你能搞定,你的代码中也有大量的冗余,从Container到N之间的所有组件都要传递N需要的props
  • 所以,为了解决层层传递,react-redux就出现了
    它利用了react中的context,在Container的context里创建store,使Container的所有子组件,孙组件等等都可以直接获取store中的内容。
    图片描述

二、修改store

我曾在快速理解redux中提起,为了解决模块(组件)之间需要共享数据 和 数据可能被任意修改导致不可预料的结果 的矛盾,redux团队创建了dispatch。So 不可预料的结果究竟是什么?

我们思考一个问题,假如所有的组件都以 store.xxx = xxx; // 伪代码 这种方式修改全局变量,会引发什么问题?

我们再思考,为何python等语言会存在线程锁,数据库也存在锁,操作系统的生产者/消费者问题等等
假如A和B同时修改store,store是遵从A还是遵从B?

为了避免以上情况引发死锁redux想出了一个办法:封装一个dispatch函数,接收一个action对象作为参数,每当组件想要修改store时必须给dispatch传递action,然后再store内部根据action对象的type将dispatch分发到相应的队列中,每一时刻仅执行一个dispatch

三、redux异步问题

思考这样一个情景,我们从后端的接口获取了数据,我们想将其存入store中。但是当执行到reducer时,数据是否已经获取到?假如没有,又该怎么办?
就在此时,中间件出现了,例如 redux-saga, redux-thunk 等等。

  • redux-saga 使用了generate生成器,使开发者可以按同步思路的书写异步代码,再根据action的type选择相应reducer更新store

    function *fetchNodeDetailByNodeId({ payload: { nodeId } }, { call, put }) {
      try {
        const { data, status }= yield call(fetchNodeDetailByNodeId, nodeId)
        if (data && status.errmsg === 'success') {
          yield put({
            type: 'setStates',
            payload: {
              nodeDetailData: data,
            },
          });
        } else {
          message.info('开了个小差,再试一次吧..');
        }
      } catch (error) {
        console.log(error);
      }
    },

心难收
717 声望32 粉丝