# `bindActionCreators(actionCreators, dispatch)`
把一個 value 為不同 [action creator](../Glossary.md#action-creator) 的對象,轉成擁有同名 key 的對象。同時使用 [`dispatch`](Store.md#dispatch) 對每個 action creator 進行包裝,以便可以直接調用它們。
一般情況下你可以直接在 [`Store`](Store.md) 實例上調用 [`dispatch`](Store.md#dispatch)。如果你在 React 中使用 Redux,[react-redux](https://github.com/gaearon/react-redux) 會提供 [`dispatch`](Store.md#dispatch) 函數讓你直接調用它 。
惟一會使用到 `bindActionCreators` 的場景是當你需要把 action creator 往下傳到一個組件上,卻不想讓這個組件覺察到 Redux 的存在,而且不希望把 [`dispatch`](Store.md#dispatch) 或 Redux store 傳給它。
為方便起見,你也可以傳入一個函數作為第一個參數,它會返回一個函數。
#### 參數
1. `actionCreators` (_Function_ or _Object_): 一個 [action creator](../Glossary.md#action-creator),或者一個 value 是 action creator 的對象。
2. `dispatch` (_Function_): 一個由 [`Store`](Store.md) 實例提供的 [`dispatch`](Store.md#dispatch) 函數。
#### 返回值
(_Function_ or _Object_): 一個與原對象類似的對象,只不過這個對象的 value 都是會直接 dispatch 原 action creator 返回的結果的函數。如果傳入一個單獨的函數作為 `actionCreators`,那么返回的結果也是一個單獨的函數。
#### 示例
#### `TodoActionCreators.js`
```js
export function addTodo(text) {
return {
type: 'ADD_TODO',
text
}
}
export function removeTodo(id) {
return {
type: 'REMOVE_TODO',
id
}
}
```
#### `SomeComponent.js`
```js
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)
```
#### 小貼士
- 你或許要問:為什么不直接把 action creator 綁定到 store 實例上,就像傳統的 Flux 那樣?問題在于,這對于需要在服務端進行渲染的同構應用會有問題。多數情況下,你的每個請求都需要一個獨立的 store 實例,這樣你可以為它們提供不同的數據,但是在定義的時候綁定 action creator,你就只能使用一個唯一的 store 實例來對應所有請求了。
- 如果你使用 ES5,無法使用 `import * as` 語法,你可以把 `require('./TodoActionCreators')` 作為第一個參數傳給 `bindActionCreators`。惟一要注意的是作為 `actionCreators` 參數的對象它的 value 需要是函數。模塊加載系統并不重要。
- 自述
- 介紹
- 動機
- 核心概念
- 三大原則
- 先前技術
- 學習資源
- 生態系統
- 示例
- 基礎
- Action
- Reducer
- Store
- 數據流
- 搭配 React
- 示例:Todo List
- 高級
- 異步 Action
- 異步數據流
- Middleware
- 搭配 React Router
- 示例:Reddit API
- 下一步
- 技巧
- 配置 Store
- 遷移到 Redux
- 使用對象展開運算符
- 減少樣板代碼
- 服務端渲染
- 編寫測試
- 計算衍生數據
- 實現撤銷重做
- 子應用隔離
- 組織 Reducer
- Reducer 基礎概念
- Reducer 基礎結構
- Reducer 邏輯拆分
- Reducer 重構示例
- combineReducers 用法
- combineReducers 進階
- State 范式化
- 管理范式化數據
- Reducer 邏輯復用
- 不可變更新模式
- 初始化 State
- 結合 Immutable.JS 使用 Redux
- 常見問題
- 綜合
- Reducer
- 組織 State
- 創建 Store
- Action
- 不可變數據
- 代碼結構
- 性能
- 設計哲學
- React Redux
- 其它
- 排錯
- 詞匯表
- API 文檔
- createStore
- Store
- combineReducers
- applyMiddleware
- bindActionCreators
- compose
- react-redux 文檔
- API
- 排錯