Redux 源码解读之 bindActionCreators

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
}
  1. 如果参数 actionCreators 类型为 function,则直接执行这个函数。
  2. 如果参数 actionCreators 类型不是非 null 的对象,抛错;
  3. 如果参数 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>
  }
}
发布了252 篇原创文章 · 获赞 2360 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/103155624