bindActionCreators
bindActionCreators(actionCreators, dispatch)
把 action creators 轉(zhuǎn)成擁有同名 keys 的對(duì)象票渠,但使用 dispatch 把每個(gè) action creator 包圍起來(lái),這樣可以直接調(diào)用它們昂秃。
一般情況下你可以直接在 Store 實(shí)例上調(diào)用 dispatch杜窄。如果你在 React 中使用 Redux,react-redux 會(huì)提供 dispatch 塞耕。
惟一使用 bindActionCreators 的場(chǎng)景是當(dāng)你需要把 action creator 往下傳到一個(gè)組件上扫外,卻不想讓這個(gè)組件覺(jué)察到 Redux 的存在,而且不希望把 Redux store 或 dispatch 傳給它筛谚。
為方便起見(jiàn),你可以傳入一個(gè)函數(shù)作為第一個(gè)參數(shù)蚊伞,它會(huì)返回一個(gè)函數(shù)吮铭。
參數(shù)
actionCreators (Function or Object): 一個(gè) action creator,或者鍵值是 action creators 的對(duì)象别垮。
dispatch (Function): 一個(gè) dispatch 函數(shù)扎谎,由 Store 實(shí)例提供。
返回值
- (Function or Object): 一個(gè)與原對(duì)象類似的對(duì)象胧奔,只不過(guò)這個(gè)對(duì)象中的的每個(gè)函數(shù)值都可以直接 dispatch action预吆。如果傳入的是一個(gè)函數(shù),返回的也是一個(gè)函數(shù)。
示例
TodoActionCreators.js
export function addTodo(text) {
return {
type: 'ADD_TODO',
text
};
}
export function removeTodo(id) {
return {
type: 'REMOVE_TODO',
id
};
}
- SomeComponent.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 {
componentDidMount() {
// 由 react-redux 注入:
let { dispatch } = this.props;
// 注意:這樣做行不通:
// TodoActionCreators.addTodo('Use Redux');
// 你只是調(diào)用了創(chuàng)建 action 的方法。
// 你必須要 dispatch action 而已宿礁。
// 這樣做行得通:
let action = TodoActionCreators.addTodo('Use Redux');
dispatch(action);
}
render() {
// 由 react-redux 注入:
let { todos, dispatch } = this.props;
// 這是應(yīng)用 bindActionCreators 比較好的場(chǎng)景:
// 在子組件里,可以完全不知道 Redux 的存在控汉。
let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch);
console.log(boundActionCreators);
// {
// addTodo: Function,
// removeTodo: Function
// }
return (
<TodoList todos={todos}
{...boundActionCreators} />
);
// 一種可以替換 bindActionCreators 的做法是直接把 dispatch 函數(shù)
// 和 action creators 當(dāng)作 props
// 傳遞給子組件
// return <TodoList todos={todos} dispatch={dispatch} />;
}
}
export default connect(
state => ({ todos: state.todos })
)(TodoListContainer)
你或許要問(wèn):為什么不直接把 action creators 綁定到 store 實(shí)例上返吻,就像傳統(tǒng) Flux 那樣测僵?問(wèn)題是這樣做的話如果開(kāi)發(fā)同構(gòu)應(yīng)用,在服務(wù)端渲染時(shí)就不行了捍靠。多數(shù)情況下,你 每個(gè)請(qǐng)求都需要一個(gè)獨(dú)立的 store 實(shí)例,這樣你可以為它們提供不同的數(shù)據(jù)吊宋,但是在定義的時(shí)候綁定 action creators璃搜,你就可以使用一個(gè)唯一的 store 實(shí)例來(lái)對(duì)應(yīng)所有請(qǐng)求了。
如果你使用 ES5这吻,不能使用 import * as 語(yǔ)法,你可以把 require('./TodoActionCreators') 作為第一個(gè)參數(shù)傳給 bindActionCreators怠硼。惟一要考慮的是 actionCreators 的參數(shù)全是函數(shù)移怯。模塊加載系統(tǒng)并不重要。