redux v3.7.2源码解读与学习之 bindActionCreators
redux
是什么、有什么作用,解决什么问题,如果你还不知道,请先去这里: redux中文文档
下面的文章适合对redux有一定理解和使用经验的人
项目github地址:https://github.com/wangweianger/redux-source-code-learning
如果你觉得对你有帮助的话记得给我一个star呢
bindActionCreators
干的事情太简单了,都不值得用一篇文章来说明,一句话带过的事,不过还是请允许我啰嗦的阐述一下吧。
还是一如既往的先奉上bindActionCreators的源代码:
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"?`
)
}
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 creator 往下传到一个组件上,却不想让这个组件觉察到 Redux 的存在,而且不希望把 Redux store 或 dispatch 传给它。
用代码阐述就是:
let actions = {
addTodo:...,
addTodoTwo:...
}
// 父组件
class TodoListContainer extends Component {
render() {
// 由 react-redux 注入:
let { dispatch } = this.props;
let boundActionCreators = bindActionCreators(actions, dispatch);
return (
<childContainer {...boundActionCreators} />
);
}
}
// 子组件
class childContainer extends Component {
componentDidMount(){
this.props.addTodo();
this.props.addTodoTwo();
}
}
子组件中不需要知道dispatch || redux 的存在,却可以调用addTodo和addTodoTwo方法去更新store的数据。
下面我用测试案例的方式去看源代码:
//测试案例
import { createStore,bindActionCreators } from './redux'
const ADD_TODO = 'ADD_TODO'
function addTodo(text) {
return {
type: 'ADD_TODO',
text:'Add Something one'
};
}
function addTodoTwo(text) {
return {
type: 'ADD_TODO',
text:'Add Something two'
};
}
let actions = {
addTodo:addTodo,
addTodoTwo:addTodoTwo
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([ action.text ])
default:
return state
}
}
let store = createStore(todos, [ 'Use Redux' ])
let boundActionCreators = bindActionCreators(actions, store.dispatch);
//boundActionCreators 传递给子组件调用,子组件不需要引入dispatch 直接调用即可
//子组件直接调用
boundActionCreators.addTodo()
console.log(store.getState())
boundActionCreators.addTodoTwo()
console.log(store.getState())
下面我们来推理源代码运行流程(去掉了检查抛错部分):
function bindActionCreator(actionCreator, dispatch) {
return (...args) => dispatch(actionCreator(...args))
}
/*此处
actionCreators= { addTodo:addTodo, addTodoTwo:addTodoTwo }
dispatch = store.dispatch
*/
export default function bindActionCreators(actionCreators, dispatch) {
//因为actionCreators为Object,因此跳过此条件
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
// keys=[ addTodo, addTodoTwo ]
const keys = Object.keys(actionCreators)
// 定义 返回dispatch集合
const boundActionCreators = {}
//循环遍历keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const actionCreator = actionCreators[key]
/* actionCreator === 'function' 为true 因此返回
boundActionCreators['addTodo'] = (...args) => dispatch(actionCreator(...args)),
boundActionCreators['addTodoTwo'] = (...args) => dispatch(actionCreator(...args))
*/
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
/* 最终
boundActionCreators={
addTodo: (...args) => dispatch(actionCreator(...args)),
addTodoTwo: (...args) => dispatch(actionCreator(...args))
}
*/
return boundActionCreators
}
分析得出:最终得到的boundActionCreators方法再子组件中调用就不需要再提供dispatch了。 你懂了吗?反正我是懂了。
总结:
此次分析比较啰嗦,但却很详细,对不了解redux源码的人会有一定的帮助
对熟悉redux功能的人更能了解所以然,用之,揪其根本
同时对自己也是一次详细了解redux功能的一次锻炼
为实现另外的库打好基础,比如
react-redux
然每个人都会犯错误,在理解中我一定有错误的地方,望体谅
既然已经熟悉了redux
的实现原理和解决的问题,接下来就应该应用上来,无可争议当前redux
最大的使用场景就是react
框架,怎么更好的把redux
库与其他框架更优美的紧密结合起来,因此react-redux
是我们最好的学习库了。接下来就详细的去看看react-redux
的源码吧。
zane
发表于 2017-12-18 12:13:42,添加在了 redux
标签下打赏
您的支持将鼓励我继续努力与分享。


评论
正在加载验证码......