首页 男生 其他 深入浅出React和Redux

3.2.5 React-Redux

深入浅出React和Redux 程墨 4644 2021-04-06 02:29

  您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!

  

  3.2.5 React-Redux

  在上面两节中,我们了解了改进React应用的两个方法,第一是把一个组件拆分为容器组件和傻瓜组件,第二是使用React的Context来提供一个所有组件都可以直接访问的Context,也不难发现,这两种方法都有套路,完全可以把套路部分抽取出来复用,这样每个组件的开发只需要关注于不同的部分就可以了。

  实际上,已经有这样的一个库来完成这些工作了,这个库就是react-redux。

  在本书的chapter-03/react-redux目录下,可以看到利用react-redux实现的Control-Panel版本,因为使用了react-redux,所以它是所有实现方式中代码最精简的一个例子。

  我们只看不同的部分。在src/index.js中,代码几乎和react_with_context一模一样,唯一的区别就是我们不再使用自己实现的Provider,而是从react-redux库导入Provider,代码如下:

  import {Provider} from 'react-redux';

  有了react-redux,视图文件src/views/Counter.js和src/Summary.js中的代码可以变得相当简洁。

  在前面的redux_smart_dumb和redux_with_context例子中,我们实际上分别实现了react-redux的两个最主要功能:

  ·connect:连接容器组件和傻瓜组件;

  ·Provider:提供包含store的context。

  现在我们直接使用react-redux提供的这两个功能了,让我们分别来详细介绍。

  1.connect

  以Counter组件为例,和redux_with_context中的代码不同,react-redux的例子中没有定义CounterContainer这样命名的容器组件,而是直接导出了一个这样的语句。

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

  第一眼看去,会让人觉得这不是正常的JavaScript语法。其实,connect是react-redux提供的一个方法,这个方法接收两个参数mapStateToProps和mapDispatch-ToProps,执行结果依然是一个函数,所以才可以在后面又加一个圆括号,把connect函数执行的结果立刻执行,这一次参数是Counter这个傻瓜组件。

  这里有两次函数执行,第一次是connect函数的执行,第二次是把connect函数返回的函数再次执行,最后产生的就是容器组件,功能相当于前面redux_smart_dumb中的CounterContainer。

  当然,我们也可以把connect的结果赋值给一个变量CounterContainer,然后再export这个CounterContainer,只是connect已经大大简化了代码,习惯上可以直接导出函数执行结果,也不用纠结如何命名这个变量。

  这个connect函数具体做了什么工作呢?

  作为容器组件,要做的工作无外乎两件事:

  ·把Store上的状态转化为内层傻瓜组件的prop;

  ·把内层傻瓜组件中的用户动作转化为派送给Store的动作。

  这两个工作一个是内层傻瓜对象的输入,一个是内层傻瓜对象的输出。

  这两个工作的套路也很明显,把Store上的状态转化为内层组件的props,其实就是一个映射关系,去掉框架,最后就是一个mapStateToProps函数该做的事情。这个函数命名是业界习惯,因为它只是一个模块内的函数,所以实际上叫什么函数都行,如果觉得mapStateToProps这个函数名太长,也可以叫mapState,也是业界惯常的做法。

  Counter组件对应的mapStateToProps函数代码如下:

  function mapStateToProps(state, ownProps) {

  return {

  value: state[ownProps.caption]

  }

  }

  把内层傻瓜组件中用户动作转化为派送给Store的动作,也就是把内层傻瓜组件暴露出来的函数类型的prop关联上dispatch函数的调用,每个prop代表的回调函数的主要区别就是dispatch函数的参数不同,这就是mapDispatchToProps函数做的事情,和mapStateToProps一样,这么长的函数名只是习惯问题,mapDispatchToProps也可以叫做mapDispatch。

  Counter组件对应的mapDispatchToProps函数代码如下:

  function mapDispatchToProps(dispatch, ownProps) {

  return {

  onIncrement: () => {

  dispatch(Actions.increment(ownProps.caption));

  },

  onDecrement: () => {

  dispatch(Actions.decrement(ownProps.caption));

  }

  }

  }

  mapStateToProps和mapDispatchToProps都可以包含第二个参数,代表ownProps,也就是直接传递给外层容器组件的props,在ControlPanel的例子中没有用到,我们在后续章节中会有详细介绍。

  2.Provider

  我们在redux_with_context中已经完整实现了一个Provider,react-redux和我们例子中的Provider几乎一样,但是更加严谨,比如我们只要求store属性是一个object,而react-redux要求store不光是一个object,而且是必须包含三个函数的object,这三个函数分别是。

  ·subscribe

  ·dispatch

  ·getState

  拥有上述三个函数的对象,才能称之为一个Redux的store。

  另外,react-redux定义了Provider的componentWillReceiveProps函数,在React组件的生命周期中,componentWillReceiveProps函数在每次重新渲染时都会调用到,react-redux在componentWillReceiveProps函数中会检查这一次渲染时代表store的prop和上一次的是否一样。如果不一样,就会给出警告,这样做是为了避免多次渲染用了不同的Redux Store。每个Redux应用只能有一个Redux Store,在整个Redux的生命周期中都应该保持Store的唯一性。 深入浅出React和Redux

目录
设置
手机
书架
书页
评论