对于bindActionCreators,更多的是在react-redux中的connect函数中配合使用,
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
如上,connect函数接收的第二个参数为mapDispatchToProps,它可以有两种形式:函数或者对象
函数形式:
const mapDispatchToProps = (dispatch, ownProps) => ({
increment: () => dispatch(increment()),
decrement: () => dispatch(decrement())
})
简写为对象形式:
const mapDispatchToProps = {
increment,
decrement
}
那么为何这两种形式都可以呢,实际上在connect函数内部,它对mapDispatchToProps作了特殊处理,即通过bindActionCreators。这里的bindActionCreators函数接收三个参数(官方库只接收两个):
- actionCreators - 即connect传入的mapDispatchToProps
- dispatch - 即store.dispatch
- ownProps - 即传入组件本身的props
它的主要逻辑就是判断传入的mapDispatchToProps是否是函数还是对象。如果是函数,直接执行并返回;如果是对象,则对之进行改造,使之与函数类型执行的结果形式一致
/* bindActionCreators.js */
const bindActionCreator = (actionCreator, dispatch) => (...args) =>
dispatch(actionCreator(...args));
export default function bindActionCreators(actionCreators, dispatch, ownProps) {
// 如果是函数类型,直接执行返回
if (typeof actionCreators === 'function') {
return actionCreators(dispatch, ownProps);
}
if (typeof actionCreators !== 'object') {
throw new Error('bindActionCreators expected an object or a function.');
}
const boundActionCreators = {};
// 已注释,采用下面的数组reduce累加器写法
// for (let key of Object.keys(actionCreators)) {
// boundActionCreators[key] = bindActionCreator(actionCreators[key], dispatch);
// }
Object.keys(actionCreators).reduce((boundActionCreators, actionKey) => {
boundActionCreators[actionKey] = bindActionCreator(
actionCreators[actionKey],
dispatch
);
return boundActionCreators;
}, boundActionCreators);
return boundActionCreators;
}
相关文章
mini-redux系列之一:createStore
mini-redux系列之二:applyMiddleware
mini-redux系列之三:combineReducers
mini-redux系列之四:bindActionCreators
mini-react-redux系列之一:Provider
mini-react-redux系列之二:connect
redux-thunk以及自定义redux中间件
网友评论