函数意义
一般情况下派发一个动作我们使用store.dispatch(MyActionCreators.doSomething()),如何才能在自动适配环境,例如在类中使用this.props.doSomething()直接调用函数呢?这就要应用到bindActionCreators。
使用方式
纯redux使用:
// 方法1 参数1是函数
bindActionCreators(doSomething, store.dispatch);
// 方法2 参数1是object
bindActionCreators({ doSomething }, store.dispatch);
// 方法3 参数1是object
bindActionCreators({ key: doSomething }, store.dispatch);
react-redux使用:
由于mapDispatchToProps是和connect函数组合使用,因此引入connect后无需再引入store说明dispatch参数。
// 方法1
function mapDispatchToProps(dispatch) {
return bindActionCreators(doSomething, dispatch);
}
// 方法2
function mapDispatchToProps(dispatch) {
return bindActionCreators({ doSomething }, dispatch);
}
// 方法3
function mapDispatchToProps(dispatch) {
return bindActionCreators({ key: doSomething }, dispatch);
}
源码解析
import { kindOf } from './utils/kindOf'
// dispatch分发当前环境下的actionCreator函数
function bindActionCreator(actionCreator, dispatch) {
return function () {
return dispatch(actionCreator.apply(this, arguments))
}
}
/**
* Turns an object whose values are action creators, into an object with the
* same keys, but with every function wrapped into a `dispatch` call so they
* may be invoked directly. This is just a convenience method, as you can call
* `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
*
* For convenience, you can also pass an action creator as the first argument,
* and get a dispatch wrapped function in return.
*
* @param {Function|Object} actionCreators An object whose values are action
* creator functions. One handy way to obtain it is to use ES6 `import * as`
* syntax. You may also pass a single function.
*
* @param {Function} dispatch The `dispatch` function available on your Redux
* store.
*
* @returns {Function|Object} The object mimicking the original object, but with
* every action creator wrapped into the `dispatch` call. If you passed a
* function as `actionCreators`, the return value will also be a single
* function.
*/
export default function bindActionCreators(actionCreators, dispatch) {
// 参数可以是函数
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
// 参数可以是object,不能是null
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error(
`bindActionCreators expected an object or a function, but instead received: '${kindOf(
actionCreators
)}'. ` +
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
)
}
// 遍历object中的函数,将函数绑定在对应环境下,并dispatch分发出去
const boundActionCreators = {}
for (const key in actionCreators) {
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
// 返回可分发的函数形成的一个object
return boundActionCreators
}