Redux API之bindActionCreators


bindActionCreators(actionCreators,dispatch)

把 action creators 轉成擁有同名 keys 的對象,但使用 dispatch 把每個 action creator 包圍起來,這樣可以直接調用它們。

一般情況下你可以直接在 Store 實例上調用 dispatch。如果你在 React 中使用 Redux,react-redux 會提供 dispatch 。

惟一使用 bindActionCreators 的場景是當你需要把 action creator 往下傳到一個組件上,卻不想讓這個組件覺察到 Redux 的存在,而且不希望把 Redux store 或 dispatch 傳給它。

為方便起見,你可以傳入一個函數作為第一個參數,它會返回一個函數。

參數

  1. actionCreators (Function or Object): 一個 action creator,或者鍵值是 action creators 的對象。

  2. dispatch (Function): 一個 dispatch 函數,由 Store 實例提供。

返回值

(Function or Object): 一個與原對象類似的對象,只不過這個對象中的的每個函數值都可以直接 dispatch action。如果傳入的是一個函數,返回的也是一個函數。

示例

 1 TodoActionCreators.js
 2 
 3 export function addTodo(text) {
 4   return {
 5     type: 'ADD_TODO',
 6     text
 7   };
 8 }
 9 
10 export function removeTodo(id) {
11   return {
12     type: 'REMOVE_TODO',
13     id
14   };
15 }
16 SomeComponent.js
17 
18 import { Component } from 'react';
19 import { bindActionCreators } from 'redux';
20 import { connect } from 'react-redux';
21 
22 import * as TodoActionCreators from './TodoActionCreators';
23 console.log(TodoActionCreators);
24 // {
25 //   addTodo: Function,
26 //   removeTodo: Function
27 // }
28 
29 class TodoListContainer extends Component {
30   componentDidMount() {
31     // 由 react-redux 注入:
32     let { dispatch } = this.props;
33 
34     // 注意:這樣做行不通:
35     // TodoActionCreators.addTodo('Use Redux');
36 
37     // 你只是調用了創建 action 的方法。
38     // 你必須要 dispatch action 而已。
39 
40     // 這樣做行得通:
41     let action = TodoActionCreators.addTodo('Use Redux');
42     dispatch(action);
43   }
44 
45   render() {
46     // 由 react-redux 注入:
47     let { todos, dispatch } = this.props;
48 
49     // 這是應用 bindActionCreators 比較好的場景:
50     // 在子組件里,可以完全不知道 Redux 的存在。
51 
52     let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch);
53     console.log(boundActionCreators);
54     // {
55     //   addTodo: Function,
56     //   removeTodo: Function
57     // }
58 
59     return (
60       <TodoList todos={todos}
61                 {...boundActionCreators} />
62     );
63 
64     // 一種可以替換 bindActionCreators 的做法是直接把 dispatch 函數
65     // 和 action creators 當作 props 
66     // 傳遞給子組件
67     // return <TodoList todos={todos} dispatch={dispatch} />;
68   }
69 }
70 
71 export default connect(
72   state => ({ todos: state.todos })
73 )(TodoListContainer)
View Code

小貼士

  • 你或許要問:為什么不直接把 action creators 綁定到 store 實例上,就像傳統 Flux 那樣?問題是這樣做的話如果開發同構應用,在服務端渲染時就不行了。多數情況下,你 每個請求都需要一個獨立的 store 實例,這樣你可以為它們提供不同的數據,但是在定義的時候綁定 action creators,你就可以使用一個唯一的 store 實例來對應所有請求了。

  • 如果你使用 ES5,不能使用 import * as 語法,你可以把 require('./TodoActionCreators') 作為第一個參數傳給 bindActionCreators。惟一要考慮的是 actionCreators 的參數全是函數。模塊加載系統並不重要。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM