I was reading the documentation for the Redux library and it has this example:
In addition to reading the state, container components can dispatch actions. In a similar fashion, you can define a function called
mapDispatchToProps()
that receives thedispatch()
method and returns callback props that you want to inject into the presentational component.
This actually makes no sense. Why do you need mapDispatchToProps
when you already have mapStateToProps
?
They also provide this handy code sample:
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
What is this function and why it is useful?
I feel like none of the answers have crystallized why
mapDispatchToProps
is useful.This can really only be answered in the context of the
container-component
pattern, which I found best understood by first reading:Container Components then Usage with React.In a nutshell, your
components
are supposed to be concerned only with displaying stuff. The only place they are supposed to get information from is their props.Separated from "displaying stuff" (components) is:
That is what
containers
are for.Therefore, a "well designed"
component
in the pattern look like this:See how this component gets the info it displays from props (which came from the redux store via
mapStateToProps
) and it also gets its action function from its props:sendTheAlert()
.That's where
mapDispatchToProps
comes in: in the correspondingcontainer
I wonder if you can see, now that it's the
container
1 that knows about redux and dispatch and store and state and ... stuff.The
component
in the pattern,FancyAlerter
, which does the rendering doesn't need to know about any of that stuff: it gets its method to call atonClick
of the button, via its props.And ...
mapDispatchToProps
was the useful means that redux provides to let the container easily pass that function into the wrapped component on its props.All this looks very like the todo example in docs, and another answer here, but I have tried to cast it in the light of the pattern to emphasize why.
(Note: you can't use
mapStateToProps
for the same purpose asmapDispatchToProps
for the basic reason that you don't have access todispatch
insidemapStateToProp
. So you couldn't usemapStateToProps
to give the wrapped component a method that usesdispatch
.I don't know why they chose to break it into two mapping functions - it might have been tidier to have
mapToProps(state, dispatch, props)
IE one function to do both!1 Note that I deliberately explicitly named the container
FancyButtonContainer
, to highlight that it is a "thing" - the identity (and hence existence!) of the container as "a thing" is sometimes lost in the shorthandexport default connect(...)
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀syntax that is shown in most examples