React Redux mapDispatchToProps vs this.props.dispatch
So far I've used my container and component actions like this:
<Header btnMnuAction={this.props.toggleSidebar} logout={this.props.logout}/>
With the mapDispatchToProps function:
const mapDispatchToProps = (dispatch) => {
return {
toggleSidebar: () => {
dispatch(toggleSidebar());
},
logout: () => {
dispatch(logout());
}
}
};
Now I tried it this way:
<Header btnMnuAction={() => this.props.dispatch(toggleSidebar())} logout={() => this.props.dispatch(logout())} >
Please can someone explain to me what is the difference between these parameters?
Thank:)
source to share
When you use connect
from redux
and use mapDispatchToProps
, the functions returned mapDispatchToProps
are available as props, for example in the first case
const mapDispatchToProps = (dispatch) => {
return {
toggleSidebar: () => {
dispatch(toggleSidebar());
},
logout: () => {
dispatch(logout());
}
}
};
From the props, you will get access to toggleSidebar
and logout
, which inside have a specific dispatch.
In the second case, if you don't pass the second argument connect
, it makes it available dispatch
by default, and then you can invoke the action usingdispatch
So, these are just two different ways to achieve the same result and internally do the same.
source to share
The base role mapDispatchToProps
is exactly what you do inside your example, however it is more flexible as it can accept not only the dispatcher, but also the state of the target component and its own props.
You can use these additional parameters to change behavior based on the state of the component (for example, if it is disabled
, then you can choose not to return any associated actions) or props (for example, if there is a cleanStorage
component in your own props, pass it by action logout
).
Using mapDispatchToProps
makes your code cleaner and better separated. Imagine doing 10+ actions and bind them manually ... Consumer components should only take specific actions, not generic ones, dispatch
and thus reduce communication with Redux and simplify maintenance and testing.
Using some additional functionality, you can define a simpler function bind
where you simply bind the submit function to the action creators, like this:
const bind => actions => dispatch =>
Object.entries(actions)
.map(([key, action]) => [key, (...args) => dispatch(action(...args)])
.reduce((acc, ([key, boundAction]) => ({...acc, [key]: boundAction}), {})
connect(mapStateToProps, bind( { toggleSidebar, logout } ), ...)(Component)
Or just use bindActionCreators (actionCreators, dispatch) to shrink the template:
import { bindActionCreators } from 'redux';
connect(
mapStateToProps,
dispatch => bindActionCreators( { toggleSidebar, logout }, dispatch),
...
)(Component)
source to share
There isn't really a significant difference. The only difference I can think of is that the first approach creates a new inline function every time the render method is called. Other than that, they are just different ways to do the same.
There is another way of coding and a cleaner approach for mapDispatchToProps
. If you are just calling a function inside a dispatcher call in mapDispatchToProps
, you can work around it all together and pass your methods in the object directly as the second argument to the method connect
.
connect(mapStateToProps, {toggleSidebar, logout})(Component)
source to share