bindActionCreators(actionCreators, dispatch)
Convierte un objeto cuyos valores son creadores de acciones, en un objeto, con las mismas claves, pero donde cada creador de acciones está envuelto en una llamada a dispatch
para ser invocada inmediatamente.
Normalmente solo deberías llamar a dispatch
directamente desde tu instancia del Store
. Si usas Redux con React, react-redux te provee de la función dispatch
para que las llames directamente.
En único caso de uso para bindActionCreatores
es cuando quieres pasar un creador de acciones a un componente que no sabe nada de Redux y no quieres pasarle dispatch
o el store de Redux.
Por conveniencia, también puedes pasar una sola función como primer argumento, y obtener una función devuelta.
Parametros
actionCreators
(Función u Objeto): Un creador de acciones, o un objeto cuyos valores son creadores de acciones.dispatch
(Función): La funcióndispatch
disponible en la instancia delStore
.
Regresa
(Función u Objeto): Un objeto similar al original, pero donde cada función despacha inmediatamente la acción regresada por el creador de acciones correspondiente. Si pasas una función como actionCreators
, el valor devuelto va a ser también una única función.
Ejemplo
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() {
// Inyectado por react-redux:
let { dispatch } = this.props
// Nota: esto no funciona
// TodoActionCreators.addTodo('Use Redux')
// Solamente estas llamando una función que crea una acción
// ¡También deberías despachar la acción!
// Esto funcionaría
let action = TodoActionCreators.addTodo('Use Redux')
dispatch(action)
}
render() {
// Inyectado por react-redux:
let { todos, dispatch } = this.props
// Acá hay un buen caso de uso para bindActionCreators:
// Quieres un componente hijo que este completamente desatendido de Redux
let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
console.log(boundActionCreators)
// {
// addTodo: Function,
// removeTodo: Function
// }
return (
<TodoList todos={todos}
{...boundActionCreators} />
)
// Una alternativa a bindActionCreators es enviar
// la función dispatch hacia abajo , pero entonces tu componente
// hijo necesita importar los creadores de acciones y saber sobre ellos
// return <TodoList todos={todos} dispatch={dispatch} />
}
}
export default connect(
state => ({ todos: state.todos })
)(TodoListContainer)
Consejos
Capaz te preguntes: ¿por qué no unimos los creadores de acciones a la instancia del store directamente, como en Flux? El problema es que eso no funciona en aplicaciones universales que deben renderizar en el servidor. Normalmente vas a querer tener una instancia del store por cada petición así puedes usarlas con diferentes datos, pero conectar los creadores de acciones durante su definición significa que estas atascado con un único instancia por petición.
Si usas ES5, en vez de usar la sintaxis
import * as
puedes simplemente pasarrequire('./TodoActionCreators')
abindActionCreators
como primer argumento. Lo único que te tiene que importar es que los valores del argumentoactionCreators
sean funciones. El sistema de módulo no importa.