reactjs - react - ¿Qué es mapDispatchToProps?
react redux mapstate to props (6)
Estaba leyendo la documentación de la biblioteca Redux y tiene este ejemplo:
Además de leer el estado, los componentes del contenedor pueden enviar acciones. De manera similar, puede definir una función llamada
mapDispatchToProps()
que recibe el métododispatch()
y devuelve los accesorios de devolución de llamada que desea inyectar en el componente de presentación.
Esto en realidad no tiene sentido.
¿Por qué necesita
mapDispatchToProps
cuando ya tiene
mapStateToProps
?
También proporcionan esta práctica muestra de código:
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
¿Alguien puede explicar en términos simples qué es esta función y por qué es útil?
Ahora suponga que hay una acción para redux como:
export function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
Cuando lo importas,
import {addTodo} from ''./actions'';
class Greeting extends React.Component {
handleOnClick = () => {
this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
}
render() {
return <button onClick={this.handleOnClick}>Hello Redux</button>;
}
}
const mapDispatchToProps = dispatch => {
return {
onTodoClick: () => { // handles onTodoClick prop''s call here
dispatch(addTodo())
}
}
}
export default connect(
null,
mapDispatchToProps
)(Greeting);
Como el nombre de la función dice
mapDispatchToProps()
,
mapDispatchToProps()
acción de
dispatch
a los accesorios (los accesorios de nuestro componente)
Por lo tanto, prop
onTodoClick
es una clave para la función
mapDispatchToProps
que delega más
addTodo
para despachar la acción
addTodo
.
Además, si desea recortar el código y omitir la implementación manual, puede hacerlo,
import {addTodo} from ''./actions'';
class Greeting extends React.Component {
handleOnClick = () => {
this.props.addTodo();
}
render() {
return <button onClick={this.handleOnClick}>Hello Redux</button>;
}
}
export default connect(
null,
{addTodo}
)(Greeting);
Que significa exactamente
const mapDispatchToProps = dispatch => {
return {
addTodo: () => {
dispatch(addTodo())
}
}
}
Básicamente es una taquigrafía. Entonces, en lugar de tener que escribir:
this.props.dispatch(toggleTodo(id));
Usaría mapDispatchToProps como se muestra en su código de ejemplo, y luego escribiría en otro lugar:
this.props.onTodoClick(id);
o más probablemente en este caso, lo tendrías como el controlador de eventos:
<MyComponent onClick={this.props.onTodoClick} />
Hay un video útil de Dan Abramov sobre esto aquí: https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist
Siento que ninguna de las respuestas ha cristalizado por qué
mapDispatchToProps
es útil.
En realidad, esto solo se puede responder en el contexto del patrón de
container-component
, que encontré mejor entendido por primera lectura:
https://medium.com/@learnreact/container-components-c0e67432e005#.1a9j3w1jl
entonces
http://redux.js.org/docs/basics/UsageWithReact.html
En pocas palabras, se supone que sus
components
solo se preocupan por mostrar cosas.
El
único lugar del que se supone que deben obtener información es sus accesorios
.
Separado de "mostrar cosas" (componentes) es:
- cómo obtienes las cosas para mostrar,
- y cómo manejas los eventos.
Para eso están los
containers
.
Por lo tanto, un
component
"bien diseñado" en el patrón tiene este aspecto:
class FancyAlerter extends Component {
sendAlert = () => {
this.props.sendTheAlert()
}
render() {
<div>
<h1>Today''s Fancy Alert is {this.props.fancyInfo}</h1>
<Button onClick={sendAlert}/>
</div>
}
}
Vea cómo este componente obtiene la información que muestra de los accesorios (que provino de la tienda redux a través de
mapStateToProps
) y también obtiene su función de acción de sus accesorios:
sendTheAlert()
.
Ahí es donde entra
mapDispatchToProps
: en el
container
correspondiente
// FancyButtonContainer.js
function mapDispatchToProps(dispatch) {
return({
sendTheAlert: () => {dispatch(ALERT_ACTION)}
})
}
function mapStateToProps(state) {
return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}
export const FancyButtonContainer = connect(
mapStateToProps, mapDispatchToProps)(
FancyAlerter
)
Me pregunto si pueden verlo, ahora que es el
container
[1] el
que sabe acerca de redux y despacho, almacenamiento, estado y ... cosas.
El
component
en el patrón,
FancyAlerter
, que realiza el renderizado no necesita saber nada de eso: obtiene su método para llamar al
onClick
del botón, a través de sus accesorios.
Y ...
mapDispatchToProps
fue el medio útil que proporciona redux para permitir que el contenedor pase fácilmente esa función al componente envuelto en sus accesorios.
Todo esto se parece mucho al ejemplo de todo en los documentos, y otra respuesta aquí, pero he tratado de lanzarlo a la luz del patrón para enfatizar por qué .
(Nota: no puede usar
mapStateToProps
con el mismo propósito que
mapDispatchToProps
por la razón básica de que no tiene acceso para
dispatch
dentro de
mapStateToProp
. Por lo tanto, no puede usar
mapStateToProps
para darle al componente envuelto un método que use
dispatch
.
No sé por qué decidieron dividirlo en dos funciones de mapeo: podría haber sido más ordenado tener
mapToProps(state, dispatch, props)
IE una función para hacer ambas cosas!
[1] Tenga en cuenta que deliberadamente nombré explícitamente el contenedor
FancyButtonContainer
, para resaltar que es una "cosa": la identidad (¡y por lo tanto la existencia!) Del contenedor como "una cosa" a veces se pierde en la taquigrafía
export default connect(...)
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
sintaxis que se muestra en la mayoría de los ejemplos
mapStateToProps()
es una utilidad que ayuda a su componente a obtener el estado actualizado (que algunos otros componentes actualizan),
mapDispatchToProps()
es una utilidad que ayudará a su componente a
mapDispatchToProps()
un evento de acción (acción de envío que puede causar un cambio en el estado de la aplicación)
mapStateToProps
,
mapDispatchToProps
y
connect
desde la biblioteca
react-redux
proporciona una forma conveniente de acceder a su
state
y la función de
dispatch
de su tienda.
Básicamente, connect es un componente de orden superior, también puede pensar como un contenedor si esto tiene sentido para usted.
Por lo tanto, cada vez que se cambie su
state
se
mapStateToProps
a
mapStateToProps
con su nuevo
state
y, posteriormente, a medida que el componente de actualización de los
props
ejecute la función de representación para representar su componente en el navegador.
mapDispatchToProps
también almacena valores-clave en los
props
de su componente, generalmente toman la forma de una función.
De esta manera, puede activar el cambio de
state
desde su componente
onClick
,
onChange
events.
De documentos:
const TodoListComponent = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
function toggleTodo(index) {
return { type: TOGGLE_TODO, index }
}
const TodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
También asegúrese de estar familiarizado con React funciones sin estado y componentes de orden superior
mapStateToProps
recibe el
state
y los
props
y le permite extraer los accesorios del estado para pasarlos al componente.
mapDispatchToProps
recibe
dispatch
y
props
y está destinado a que usted enlace a los creadores de acciones para que despachen, de modo que cuando ejecuta la función resultante, la acción se despacha.
Creo que esto solo le ahorra tener que hacer
dispatch(actionCreator())
dentro de su componente, lo que lo hace un poco más fácil de leer.
https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments