soulcm / blog

2017开通
6 stars 0 forks source link

redux源码解析(二) #8

Open soulcm opened 7 years ago

soulcm commented 7 years ago

bindActinoCreators

上篇介绍了createStore,了解了redux的工作流程,此篇将介绍一个辅助函数,其实就算不使用bindActionCreators也照样可以使用redux,每次直接通过store.dispatch(action)的调用来改变状态就行,那这个函数还有什么用呢。

惟一使用 bindActionCreators 的场景是当你需要把 action creator 往下传到一个组件上,却不想让这个组件觉察到 Redux 的存在,而且不希望把 Redux store 或 dispatch 传给它。

看它的源码

function bindActionCreator(actionCreator, dispatch) {
  return (...args) => dispatch(actionCreator(...args))
}

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"?`
    )
  }

  var keys = Object.keys(actionCreators)
  var boundActionCreators = {}
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i]
    var actionCreator = actionCreators[key]
    if (typeof actionCreator === 'function') {
      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
    }
  }
  return boundActionCreators
}

其接收一个function或一个通过import * as actions from获取到的action对象,第二个参数是dispatch

当是一个对象时,会遍历每个属性,然后将其对应的actionCreator通过一个高阶函数包裹一层dispatch,这样直接调用时就可以察觉不到dispatch的存在。函数最终返回一个新的对象,各属性对应的值是已经包裹过dispatch的函数。