bindActionCreators(actionCreators, dispatch)
Преобразует объект, значения которого являются генераторами действий, в объект с теми же ключами, но каждый генератор действий обернут в вызов dispatch, чтобы их можно было вызывать непосредственно.
Обычно вы должны просто вызвать dispatch напрямую на вашем экземпляре Store. Если вы используете Redux с React, react-redux предоставит вам функцию dispatch, чтобы вы тоже могли вызвать её напрямую.
Единственный случай использования bindActionCreators — когда вы хотите передать некоторые генераторы действий компоненту, который не знает о Redux, и вы не хотите передавать dispatch или хранилище Redux.
Для удобства вы также можете передать генератор действий в качестве первого аргумента и получить функцию с обработкой dispatch в ответ.
Параметры
actionCreators(Функция или Объект): генератор действия или объект, значения которого — генераторы действий.dispatch(Функция): Функцияdispatch, доступная в экземпляреStore.
Возвращаемое значение
(Функция или Объект): Объект, имитирующий исходный объект, но каждая функция немедленно отправляет действие, возвращённое соответствующим генератором действия. Если вы передали функцию в качестве actionCreators, возвращаемое значение также будет одной функцией.
Пример
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 {
constructor(props) {
super(props)
const { dispatch } = props
// Here's a good use case for bindActionCreators:
// You want a child component to be completely unaware of Redux.
// We create bound versions of these functions now so we can
// pass them down to our child later.
this.boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
console.log(this.boundActionCreators)
// {
// addTodo: Function,
// removeTodo: Function
// }
}
componentDidMount() {
// Injected by react-redux:
let { dispatch } = this.props
// Note: this won't work:
// TodoActionCreators.addTodo('Use Redux')
// You're just calling a function that creates an action.
// You must dispatch the action, too!
// This will work:
let action = TodoActionCreators.addTodo('Use Redux')
dispatch(action)
}
render() {
// Injected by react-redux:
let { todos } = this.props
return <TodoList todos={todos} {...this.boundActionCreators} />
// An alternative to bindActionCreators is to pass
// just the dispatch function down, but then your child component
// needs to import action creators and know about them.
// return <TodoList todos={todos} dispatch={dispatch} />
}
}
export default connect(state => ({ todos: state.todos }))(TodoListContainer)Рекомендации
Вы можете спросить: почему мы не связываем генераторы действий с экземпляром хранилища сразу, как в классическом Flux? Проблема в том, что это не будет хорошо работать с универсальными приложениями, которым нужно рендерить на сервере. Скорее всего, вы захотите иметь отдельный экземпляр хранилища на запрос, чтобы подготовить их с разными данными, но привязывание генераторов действий во время их определения означает, что вы застряли с одним экземпляром хранилища для всех запросов.
Если вы используете ES5, вместо синтаксиса
import * asвы можете просто передатьrequire('./TodoActionCreators')вbindActionCreatorsв качестве первого аргумента. Единственное, что ему нужно, — это то, что значения свойствactionCreatorsявляются функциями. Система модулей не важна.
© 2015–2021 Dan Abramov
Licensed under the MIT License.
https://redux.js.org/api/bindactioncreators