上节课我们介绍了react-redux的基本使用,在不知不觉中完成了UI组件和redux的连接。这节课我们来做一些优化的事儿。

回顾

在开始这节课的内容之前,我们先来对上节课的内容来做一个简单的回顾:

  • connect函数在第一次调用时要接收两个参数
  • connect函数第一次调用时接收到的参数必须都是函数
  • 第一个函数叫mapStateToProps,返回值必须是一个对象,对象的valueredux中存的状态值,作为状态通过props传给UI组件
  • 第二个函数叫mapDispatchToProps,返回值必须是对象,对象的value必须是函数,作为操作状态的方法,通过props传给UI组件

以上便是上节课我们的主要要点,接下来我们开始这节课的内容。

优化

我们之前是已经把我们的案例完整地写了一遍,但是优化空间很大,有很多地方可以优化,那么我们一个个来,我们先从我们的容器组件开始。

我们也许在初学的时候我们的代码都是用最基础的形式写成

function mapStateToProps(state) {
  return { sum: state };
}

function mapDispatchToProps(dispatch){
  return { 
    increment: data => dispatch(createIncrementAction(data)) ,
    decrement: data => dispatch(createDecrementAction(data)),
    asyncIncrement: (data,time) =>dispatch(createAsyncIncrementAction(data,time))
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(SumUI);

这样当然是最规整的,可读性也很高,但是这么写太复杂了,我们在实际开发中肯定不会这么写,我们都会用简写方式来缩减代码量。那么我们再来看一下:

const mapStateToProps = state => ({ sum: state });

const mapDispatchToProps = dispatch => ({ 
  increment: data => dispatch(createIncrementAction(data)) ,
  decrement: data => dispatch(createDecrementAction(data)),
  asyncIncrement: (data,time) =>dispatch(createAsyncIncrementAction(data,time))
});

export default connect(mapStateToProps, mapDispatchToProps)(SumUI);

这样的话从编码的角度上来说是不是就要简单一些啊?但是这好像也没少什么东西,只是把我们的一般函数改成了箭头函数。那么我们再来做进一步简化:

export default connect(
  state => ({ sum: state }),
  dispatch => ({
    increment: data => dispatch(createIncrementAction(data)),
    decrement: data => dispatch(createDecrementAction(data)),
    asyncIncrement: (data, time) => dispatch(createAsyncIncrementAction(data, time))
  })
)(SumUI);

这样其实才是在工作中大家最经常使用的情况,我们不做什么定义的操作,定义了就直接拿来用,但是这都是在编码层面上的简写,但是接下来我们再换一种写法:

export default connect(
  state => ({ sum: state }),
  {
    increment: createIncrementAction,
    decrement: createDecrementAction,
    asyncIncrement: createAsyncIncrementAction
  }
)(SumUI);

可能有人要说,那你这不对了啊,不是两个参数都得是函数嘛我们课没有强制要求一定得传函数啊,这么写是什么意思我们先不管,我们先看效果,看能不能这么写,如果能,我们再分析,否则就要修改了。

iShot2022-01-19 13.59.21

我们来看一下,效果一切都是正常的。那么我们来分析一下问什么吧。

要想搞明白简写版,就必须搞明白原版,第一步,我们点击了+按钮之后,是不是就会调用我们传进去的increment这个key对应的函数?这个函数是什么?是不是我们定义的箭头函数?这个函数接收我们传的参数,然后执行函数体,创建动作对象并分发下去,然后到reducer执行动作,然后返回新的状态,被容器组件拿到,然后传给UI组件。这个流程是不是这么进行的?

那么我们再来看简写版,我们点击了+按钮,是不是也要掉increment这个key对应的函数?这个函数是什么?是不是我们自己写的创建动作对象的函数?那么我们传参数了吗?我们是不是把下拉框里面选中的数字传进去了,那么这一步点击事件的回调执行的东西,是不是就相当于是createIncrementAction(data)?那么这个函数的返回值是什么?是不是一个动作对象?那么表面上这个流程到这里是不是就停了?我们点击按钮了,传了参数了,创建了action对象了,但是我们没有dispatch。那不就停了嘛。但是我们实际效果好像是没有问题的啊。

那么这就是我们的另外一个没有提到过的点了,react-redux收到action对象之后,会自动分发。所以说我们不需要手动去分发了,react-redux自动就帮我们把这活儿给干了。

总结

  • mapDispathtoProps可以是一个对象
  • react-redux可以自动分发动作对象

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/simple_map_dispatch/