传统的派发action
- 在actions.js中
export const UPDATE_MODEL = Symbol()
在视图组件中
import * actions from './actions'
onClickHandler() {
store.dispatch({
type : actions.UPDATE_MODEL,
payload : 'xxxxx'
})
}
- 这样的做法不够简洁 我们发现dispatch里面的对象,可以通过提炼函数的方式抽象出来(extract method),于是就变成了以下这种形式
在actions.js中
export const UPDATE_MODEL = Symbol()
export const updateModel = (payload)=> {
return {
type : UPDATE_MODEL,
payload
}
}
在视图组件中
import * actions from './actions'
onClickHandler() {
store.dispatch(actions.updateModel('xxxxx'))
}
- 看上去已经够简洁了吧,但是这些家伙还是觉得不行,还可以提炼函数,于是就变成了下面这样
在视图组件中
onClickHandler() {
const updateModel = (dispatch,payload)=> {
dispatch(actions.updateModel(payload))
}
updateModel(store.dispatch,'xxxx')
}
bindActionCreators
bindActionCreators就是上面的3柯里化的结果
this.boundActionCreators = bindActionCreators({
updateModel : actions.updateModel
}, store.dispatch);
console.log(boundActionCreators)
/*
logs
{
updateModel : Function
}
*/
源码 :
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error(
`bindActionCreators expected an object or a function, instead received ${
actionCreators === null ? 'null' : typeof actionCreators
}. ` +
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
)
}
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
}
小结
这个函数的应用场景,主要是子组件想调用action时 有些沙雕开发者会把dispatch当成props传递下去,然后用子组件调用dispatch(xxx)
没错,正是在下。
所以redux就说,通过这个函数直接将dispatch这个过程,包装成一个函数,使得下层组件不被感知redux的存在
网友评论