Redux 源码解读之 bindActionCreators
bindActionCreator 源码地址:node_modules/redux/src/bindActionCreators.js。
bindActionCreators 的功能是将第一个参数对象转换为同名 key 对象,然后可以很方便地使用 dispatch。
一、将参数对象转换为同名 key 对象
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 boundActionCreators = {}
for (const key in actionCreators) {
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
- 如果参数 actionCreators 类型为 function,则直接执行这个函数。
- 如果参数 actionCreators 类型不是非 null 的对象,抛错;
- 如果参数 actionCreators 类型为非 null 对象,则浅复制一份给变量 boundActionCreators。返回值为 boundActionCreators 。其目的是将参数对象转换成一个同名 key 对象。
二、应用场景
当你需要将 actions 传给子组件,但是又不想子组件有任何 Redux 的存在,或者不行层层传递 dispatch 时 。可以使用 bindActionCreators。
actions:
export function addTodo(text) {
return {
type: 'ADD_TODO',
text
};
}
export function removeTodo(id) {
return {
type: 'REMOVE_TODO',
id
};
}
App:
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
const {addTodo} = this.props;
return <div>
<Item {...actions}/>
}
};
const mapDispatchToProps = (dispatch)=>{
return {
actions:bindActionCreators({addTodo,removeTodo},dispatch)
}
};
export default connect(state=>(state),mapDispatchToProps)(App);
Item:
class Item extends React.Component {
render() {
const {addTodo,removeTodo} = this.props;
return <div onClick={()=>{console.log(addTodo(1))}}>点击试试看</div>
}
}