Reputation: 71
I was under the impression that the purpose of bindActionCreators
was to wrap actionCreators
in a dispatch function, and give these new functions a name (which could be passed to components as props, via mapDispatchToProps
and connect
).
However, a tutorial I found seemed to call bindActionCreators
on a dispatch function (updatePerson
), which seems to violate the whole point of bindActionCreators
.
actions/update_person.js
import { UPDATE_PERSON } from './types';
export default function updatePerson(person) {
return dispatch => {
dispatch(updatePersonAsync(person));
}
}
function updatePersonAsync(person){
return {
type: UPDATE_PERSON,
payload: person
};
}
components/WantedCard.js
//connects redux actions to props
function mapDispatchToProps(dispatch) {
return bindActionCreators({
updatePerson: updatePerson,
deletePerson: deletePerson
}, dispatch);
}
What exactly am I getting wrong here, with my understanding? UpdatePerson is already bound(?)
This is the tutorial repo: https://github.com/lorenseanstewart/redux-wanted-list and blog post https://lorenstewart.me/2016/11/27/a-practical-guide-to-redux/
Upvotes: 2
Views: 579
Reputation: 31024
UpdatePerson is already bound(?)
No it wasn't it's just a normal function that you import
.
In order to make it play with the redux
flow cycle you need to dispatch
this function.
When you are not passing mapDispatchToProps
you get the dispatch
function as a prop to your connected component, so to use it you would have to do it like this:
this.props.dispatch(updatePerson())
If you do decide to pass mapDispatchToProps
to connect
then you will not receive dispatch
as a prop but you could wrap your actions with it:
const mapDispatchToProps = dispatch => {
return {
updatePerson: () => {
dispatch(updatePerson())
}
}
}
Or you can just pass an object:
const mapDispatchToProps = {
updatePerson,
deletePerson
}
Another way is to use bindActionCreators
(like you mentioned in your post)
With this approach you can dispatch the action with this line of code:
function mapDispatchToProps(dispatch) {
return bindActionCreators({
updatePerson: updatePerson,
deletePerson: deletePerson
}, dispatch);
}
And call it like this:
this.props.updatePerson()
Note that you can use the Shorthand property names of ES2015 if the key matches the variable
function mapDispatchToProps(dispatch) {
return bindActionCreators({
updatePerson,
deletePerson
}, dispatch);
}
Another nice approach with bindActionCreators
is to import all actions as alias (even different actions from different files):
import * as userActions from '../url';
import * as otherActions from '../otherUrl';
And then stack them all in one object (or separate them if you want):
function mapDispatchToProps(dispatch) {
const combinedActions = { ...userActions, ...otherActions };
return {
actions: bindActionCreators(combinedActions, dispatch)
};
}
Now you can refer any action via the actions
object:
this.props.actions.myAction();
this.props.actions.myOtherAction();
You can read me about the various options in the docs
Upvotes: 1