bindActionCreators 我们很少很少用到,一般只有在 react-redux 的 connect 实现中用到。
他是做什么的?他通过闭包,把 dispatch 和 actionCreator 隐藏起来,让其他地方感知不到 redux 的存在。
我们通过普通的方式来 隐藏 dispatch 和 actionCreator 试试,注意最后两行代码
const reducer = combineReducers({
counter: counterReducer,
info: infoReducer
});
const store = createStore(reducer);
/*返回 action 的函数就叫 actionCreator*/
function increment() {
return {
type: 'INCREMENT'
}
}
function setName(name) {
return {
type: 'SET_NAME',
name: name
}
}
const actions = {
increment: function () {
return store.dispatch(increment.apply(this, arguments))
},
setName: function () {
return store.dispatch(setName.apply(this, arguments))
}
}
/*注意:我们可以把 actions 传到任何地方去*/
/*其他地方在实现自增的时候,根本不知道 dispatch,actionCreator等细节*/
actions.increment(); /*自增*/
actions.setName('九部威武'); /*修改 info.name*/
我眼睛一看,这个 actions 生成的时候,好多公共代码,提取一下
const actions = bindActionCreators({ increment, setName }, store.dispatch);
来看一下 bindActionCreators 的源码,超级简单(就是生成了刚才的 actions)
/*核心的代码在这里,通过闭包隐藏了 actionCreator 和 dispatch*/
function bindActionCreator(actionCreator, dispatch) {
return function () {
return dispatch(actionCreator.apply(this, arguments))
}
}
/* actionCreators 必须是 function 或者 object */
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error()
}
const keys = Object.keys(actionCreators)
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)
}
}
return boundActionCreators
}
bindActionCreators 示例源码见 demo-8