深入浅出React+Redux(五:React-Redux)

前言

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

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

(一)React-Redux 基本概念

React+Redux基本概念

相关代码已经推送到
我的github的simple-redux分支

现在提及React-Redux的最要功能:

connect : 连接容器组件和无状态组件(stateless)
Provider : 提供包含 store 的 context(提供React-Router传递)。

(二)connect

我们以Counter组件为例子。

import React from 'react';
import {connect} from 'react-redux';
function Counter({caption, onIncrement, onDecrement, value}) {
    ...
}

// 容器组件,
// 把store上的状态转化为内层傻瓜组件的prop,
// 把内层傻瓜组件中的用户动作转化为派送给store的动作
export default connect(mapStateToProps, mapDispatchToProps)(Counter);

第一眼看去,会让人觉得这就类似thunk函数, 在函数执行完成再次返回一个函数 。

其实, connect 是 react-redux提供的一个方法,这个方法接收两个参数 mapStateToProps 和 mapDispatchToProps ,执行结果依然是一个函数,所以才可以在后面又加一个圆括号,把 connect 函数执行的结果立刻执行,这一次参数是 Counter 这个傻瓜组件。

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

总结:
这个 connect 函数具体做了什么工作呢?
作为容器组件,要做的工作无外乎两件事:

把 Store 上的状态转化为内层傻瓜组件的 prop;
把内层傻瓜组件中的用户动作转化为派送给 Store 的动作 。

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


(1)mapStateToProps

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

function mapStateToProps(state, ownProps) {
  const { demo } = state;
  return {
    value: demo[ownProps.caption]
  }
}

上面代码。mapStateToProps接受2个参数,一个是store的state,一个是组件输入的props(ownProps),使用ownProps作为参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染。


(2)mapStateToProps

mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。它可以是一个函数,也可以是一个对象。

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

import * as Actions from '../../actions/demoActions';
function mapDispatchToProps(dispatch, ownProps) {
  return {
    onIncrement: () => {
      dispatch(Actions.increment(ownProps.caption));
    },
    onDecrement: () => {
      dispatch(Actions.decrement(ownProps.caption));
    }
  }
}

上面代码。mapDispatchToProps接受2个参数,一个是store的dispatch,负责配合Actions中定义的函数,将用户的操作应该当作 Action,传给 Store。一个是组件输入的props(ownProps)

总结:
从上面代码我们可以知道,mapStateToProps 和 mapDispatchToProps 都可以包含第二个参数,代表 ownProps,也就是直接传递给外层容器组件的 props 。

前者负责把 Store 上的状态转化为内层傻瓜组件的 prop。
后者负责把内层傻瓜组件中的用户动作转化为派送给 Store 的动作 。


(三)Provider

虽然我们上章已经实现了一个Provider组件。但是react-redux 的要求更加严谨。

比如我们只要求 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 的唯一性 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值