回顾 actionCreator
接下来说说 bindActionCreators 这个方法,bindActionCreators 不难理解,但在此之前需要回顾一下我们之前讲到的 actionCreator 的概念,我们知道,要更新state树的唯一途径是发起一个action,如:
dispatch({
type: 'ADD_TODO',
text: 'ADD TODO AGAIN.'
})
复制代码
每个action都需要写type,这样每次写起来就会觉得冗余,于是产生了 actionCreator 的概念,我们写一个函数,帮我们写好指定的type,传入不同的信息载荷就可以了,如:
function addTodo(text){
return{
type: 'ADD_TODO',
text
}
}
复制代码
上面就是一个actionCreator 的例子,注意actionCreator 和action是两个不同的概念,action是对象,用来描述state发生了什么变化,而actionCreator 是函数,是用来生成action的工厂。
bindActionCreator 函数
再然后来看看bindActionCreators 方法用到的一个函数:
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}
复制代码
函数的两个参数:
- actionCreator 函数,用于生产action的工厂
- dispatch 函数,也就是Store.dispatch ()
函数非常简单,也就是将 dispatch 和 actionCreator 绑定返回一个新的函数,使用这个函数时会直接 dispatch 一个 action,变得更加简便,如:
let actionCreator = (text)=>({
type: 'ADD_TODO,
text
})
let addTodo = bindActionCreator(actionCreator , Store.dispatch)
// 调用
addTodo('ADD SOMETHING’)
// 等价于:
dispatch({
type: 'ADD_TODO',
text: 'ADD SOMETHING'
})
复制代码
也就是说 actionCreator 帮我们省略了重复书写action.type , bindActionCreator 帮我们省略了重复书写 dispatch,而且还可以隐藏 dispatch 参数。再来看看bindActionCreators方法就不难理解了:
bindActionCreators 方法
export default function bindActionCreators(actionCreators, dispatch) {
// 如果传入的actionCreators是一个函数,则直接绑定返回一个新的函数
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
// 如果传入的actionCreators是Object类型
// Object的字段都是一个个 actionCreator
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error(
`xxxx`
)
}
const keys = Object.keys(actionCreators) // 所有的key
const boundActionCreators = {} // 最终返回的对象
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const actionCreator = actionCreators[key]
// 过滤不合法的值 逐一进行绑定
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
//返回最终绑定好 actionCreator 对象
return boundActionCreators
}
复制代码
最后
总结一下 bindActionCreators 方法,首先参数dispatch是必须的,也就是Store.dispatch()。
- 如果你传入的 actionCreators 参数仅仅是一个 actionCreator 函数,那么直接绑定 actionCreator 和 dispatch,返回一个新函数,调用函数传入action的载荷,就可以直接发起一个指定type的action。
- 如果你传入的 actionCreators 参数是一个对象,那么对象的字段必须是一个个actionCreator函数,返回一个对象,对象逐一进行绑定,每个字段都是绑定好的函数,调用它们传入action的载荷,就会直接发起一个指定type的action。
使用场景
Redux文档上关于何时使用到此API是这样说的: 惟一会使用到 bindActionCreator 的场景是当你需要把 action creator 往下传到一个组件上,却不想让这个组件觉察到 Redux 的存在,而且不希望把 dispatch 或 Redux store 传给它。