• bindActionCreators(actionCreators, dispatch)
    • 参数
    • 返回值
    • 示例
    • TodoActionCreators.js
    • SomeComponent.js
    • 小贴士

    bindActionCreators(actionCreators, dispatch)

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

    一般情况下你可以直接在 Store 实例上调用 dispatch。如果你在 React 中使用 Redux,react-redux 会提供 dispatch 函数让你直接调用它 。

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

    为方便起见,你也可以传入一个函数作为第一个参数,它会返回一个函数。

    参数

    1. actionCreators (Function or Object): 一个 action creator,或者一个 value 是 action creator 的对象。

    2. dispatch (Function): 一个由 Store 实例提供的 dispatch 函数。

    返回值

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

    示例

    TodoActionCreators.js

    1. export function addTodo(text) {
    2. return {
    3. type: 'ADD_TODO',
    4. text
    5. };
    6. }
    7. export function removeTodo(id) {
    8. return {
    9. type: 'REMOVE_TODO',
    10. id
    11. };
    12. }

    SomeComponent.js

    1. import { Component } from 'react';
    2. import { bindActionCreators } from 'redux';
    3. import { connect } from 'react-redux';
    4. import * as TodoActionCreators from './TodoActionCreators';
    5. console.log(TodoActionCreators);
    6. // {
    7. // addTodo: Function,
    8. // removeTodo: Function
    9. // }
    10. class TodoListContainer extends Component {
    11. constructor(props) {
    12. super(props);
    13. const {dispatch} = props;
    14. // 这是一个很好的 bindActionCreators 的使用示例:
    15. // 你想让你的子组件完全不感知 Redux 的存在。
    16. // 我们在这里对 action creator 绑定 dispatch 方法,
    17. // 以便稍后将其传给子组件。
    18. this.boundActionCreators = bindActionCreators(TodoActionCreators, dispatch);
    19. console.log(this.boundActionCreators);
    20. // {
    21. // addTodo: Function,
    22. // removeTodo: Function
    23. // }
    24. }
    25. componentDidMount() {
    26. // 由 react-redux 注入的 dispatch:
    27. let { dispatch } = this.props;
    28. // 注意:这样是行不通的:
    29. // TodoActionCreators.addTodo('Use Redux')
    30. // 你只是调用了创建 action 的方法。
    31. // 你必须要同时 dispatch action。
    32. // 这样做是可行的:
    33. let action = TodoActionCreators.addTodo('Use Redux');
    34. dispatch(action);
    35. }
    36. render() {
    37. // 由 react-redux 注入的 todos:
    38. let { todos } = this.props;
    39. return <TodoList todos={todos} {...this.boundActionCreators} />;
    40. // 另一替代 bindActionCreators 的做法是
    41. // 直接把 dispatch 函数当作 prop 传递给子组件,但这时你的子组件需要
    42. // 引入 action creator 并且感知它们
    43. // return <TodoList todos={todos} dispatch={dispatch} />;
    44. }
    45. }
    46. export default connect(
    47. state => ({ todos: state.todos })
    48. )(TodoListContainer);

    小贴士

    • 你或许要问:为什么不直接把 action creator 绑定到 store 实例上,就像传统的 Flux 那样?问题在于,这对于需要在服务端进行渲染的同构应用会有问题。多数情况下,你的每个请求都需要一个独立的 store 实例,这样你可以为它们提供不同的数据,但是在定义的时候绑定 action creator,你就只能使用一个唯一的 store 实例来对应所有请求了。

    • 如果你使用 ES5,无法使用 import * as 语法,你可以把 require('./TodoActionCreators') 作为第一个参数传给 bindActionCreators。惟一要注意的是作为 actionCreators 参数的对象它的 value 需要是函数。模块加载系统并不重要。