Redux学习之bindActionCreators

1,866 阅读2分钟

定义

把一个 value 为不同 action creator 的对象,转成拥有同名 key 的对象。同时使用 dispatch 对每个 action creator 进行包装,以便可以直接调用它们。

简单来讲,bindActionCreators的作用是将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容。

参数

  • actionCreators (Function or Object): 一个 action creator,或者一个 value 是 action creator 的对象。
  • dispatch (Function): 一个由 Store 实例提供的 dispatch 函数

返回值

(Function or Object): 一个与原对象类似的对象,只不过这个对象的 value 都是会直接 dispatch 原 action creator 返回的结果的函数。如果传入一个单独的函数作为 actionCreators,那么返回的结果也是一个单独的函数。

代码示例

TodoActionCreators.js
``` export function addTodo(text) { return { type: 'ADD_TODO', text }; }

export function removeTodo(id) { return { type: 'REMOVE_TODO', id }; }

<table ><tr><td bgcolor=#999 >SomeComponent.js</td></tr></table>

import { Component } from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux';

import * as TodoActionCreators from './TodoActionCreators'; console.log(TodoActionCreators); // { // addTodo: Function, // removeTodo: Function // }

class TodoListContainer extends Component { constructor(props) { super(props);

const {dispatch} = props;

// 这是一个很好的 bindActionCreators 的使用示例:
// 你想让你的子组件完全不感知 Redux 的存在。
// 我们在这里对 action creator 绑定 dispatch 方法,
// 以便稍后将其传给子组件。

this.boundActionCreators = bindActionCreators(TodoActionCreators, dispatch);
console.log(this.boundActionCreators);
// {
//   addTodo: Function,
//   removeTodo: Function
// }

}

componentDidMount() { // 由 react-redux 注入的 dispatch: let { dispatch } = this.props;

// 注意:这样是行不通的:
// TodoActionCreators.addTodo('Use Redux')

// 你只是调用了创建 action 的方法。
// 你必须要同时 dispatch action。

// 这样做是可行的:
let action = TodoActionCreators.addTodo('Use Redux');
dispatch(action);

}

render() { // 由 react-redux 注入的 todos: let { todos } = this.props;

return <TodoList todos={todos} {...this.boundActionCreators} />;

// 另一替代 bindActionCreators 的做法是
// 直接把 dispatch 函数当作 prop 传递给子组件,但这时你的子组件需要
// 引入 action creator 并且感知它们

// return <TodoList todos={todos} dispatch={dispatch} />;

} }

export default connect( state => ({ todos: state.todos }) )(TodoListContainer);