ReactRedux是react和redux合用时需要的组件。
源码整体结构
代码整体结构和redux相似:
- 检测环境,挂载reactredux
- 功能代码整体结构如下,采用_ webpack_require_方法帮助各个模块相互获取,可以看出最终对外导出的是模块0
function(react, redux) {
return(function(modules) {
function __webpack_require__(moduleId) {
//根据模块id获取后面数组中的模块
return module.exports;
}
return __webpack_require__(0);
) ([//模块0-13])
})
各模块功能
- 0:最终导出的属性和方法,Provider和connet
- 1:react
- 2:对store属性类型(subscribe,dispatch,getState方法)的检验
- 3:异常
- 4:Provider
- 5 : connect
- 6:shallowEqual,判断两个对象是否相等
- 7:bindActionCreators,redux的方法,自动dispatch action
- 8:hoistNonReactStatics,将源组件除react属性的属性复制到目标组件
- 9:invariant
- 10、11、12:plain object对象校验
- 13:redux
以上各模块,基本都是Provider和connet的辅助模块
Provider
Provider是一个react组件,在使用reactredux时,它默认为react组件数的最顶端,但是它自己本身没有dom信息,render直接返回子组件
Provider的作用是在props中保存store,并且采用react的getChildContext这一方法,使自组件可以直接访问store
用法如下
render(
<Provider store={store}>
<Main />
</Provider>,
dom
);
store就是采用redux生成的
connect
connect()返回一个函数,这个返回的函数来接受一个组件类作为参数,最后返回和 Redux store 关联起来的新组件,使用如下
connect([mapStateToProps], mapDispatchToProps], [mergeProps], [options])(mainComponent)
- [mapStateToProps(state, [ownProps]): stateProps]: 第一个可选参数是一个函数,只有指定了这个参数,这个关联(connected)组件才会监听 Redux Store 的更新,每次更新都会调用 mapStateToProps 这个函数,返回一个字面量对象将会合并到组件的 props 属性。 ownProps 是可选的第二个参数,它是传递给组件的 props,当组件获取到新的 props 时,ownProps 都会拿到这个值并且执行 mapStateToProps 这个函数。
- [mapDispatchProps(dispatch, [ownProps]): dispatchProps]: 这个函数用来指定如何传递 dispatch 给组件,在这个函数里面直接 dispatch action creator,返回一个字面量对象将会合并到组件的 props 属性,这样关联组件可以直接通过 props 调用到 action, Redux 提供了一个 bindActionCreators() 辅助函数来简化这种写法。 如果省略这个参数,默认直接把 dispatch 作为 props 传入。ownProps 作用同上。
一个具体一点的例子
import React, { Component } from 'react';
import someActionCreator from './actions/someAction';
import * as actionCreators from './actions/otherAction';
function mapStateToProps(state) {
return {
propName: state.propName
};
}
function mapDispatchProps(dispatch) {
return {
someAction: (arg) => dispatch(someActionCreator(arg)),
otherActions: bindActionCreators(actionCreators, dispatch)
};
}
class App extends Component {
render() {
// `mapStateToProps` 和 `mapDispatchProps` 返回的字段都是 `props`
const { propName, someAction, otherActions } = this.props;
return (
<div onClick={someAction.bind(this, 'arg')}>
{propName}
</div>
);
}
}
export default connect(mapStateToProps, mapDispatchProps)(App);
如前所述,这个 connected 的组件必须放到 的容器里面,当 State 更改的时候就会自动调用 mapStateToProps 和 mapDispatchProps 从而更新组件的 props。 组件内部也可以通过 props 调用到 action,如果没有省略了 mapDispatchProps,组件要触发 action 就必须手动 dispatch,类似这样:this.props.dispatch(someActionCreator(‘arg’))。