I'm wondering how to use async action creators in mapDispatchToProps
for react-redux
's connect
. I'm using the redux-thunk
middleware and the following is my mapDispatchToProps
:
function mapDispatchToProps(dispatch) {
return {
foo: function() {
dispatch(someAction());
return function asyncAction(dispatch, getState) {
console.log("An async action!");
dispatch(someOtherAction(getState().foo));
};
}
}
}
However, when I do the above, the async action does not get executed. What is the correct way to do this?
I suggest declaring your actual thunk (someOtherAction
) differently. In the following example, asyncAction
is an async action creator which returns a thunk. The thunk can then dispatch other actions (after a promise resolves for example).
function asyncActionCreator () {
return (dispatch, getState) => {
dispatch(someAction());
someAsyncStuff().then(() => {
dispatch(someOtherAction(getState().foo);
});
}
}
function mapDispatchToProps(dispatch) {
return {
foo: () => dispatch(asyncActionCreator())
}
}
For completeness I'm going to add this.
I needed to dispatch 2 actions using 1 action creator but the second action was depending on the result of the first. The second action also needed access to a different slice of the store so I couldn't use the same reducer I was using to set the first value.
My mapDispatchToProps, using redux-thunk, ended up looking as follow:
import constants from '../constants';
const mapDispatchToProps = (dispatch) => {
return {
setValuesToStore: (value) => {
const firstAction = {
type: constants.SET_FIRST_VALUE,
value,
}
dispatch(firstAction)
dispatch(secondAction())
function secondAction() {
return (dispatch, getState) => {
const state = getState()
dispatch({
type: constants.SET_SECOND_VALUE,
state,
})
}
}
}
}
}
This way I didn't need to import the store as a module, which I found very ugly. No biggie, just hope this helps.
Although the accepted answer is clearly preferable, I believe this small modification to your code might also help to understand how this mechanism works:
function mapDispatchToProps(dispatch) {
return {
foo: () => dispatch(function() { // <-- Note the dispatch!
dispatch(someAction());
return function asyncAction(dispatch, getState) {
console.log("An async action!");
dispatch(someOtherAction(getState().foo));
};
}()) // <-- Note the IIFE!
}
}
Your original thunk-creating function (associated with foo
) here must actually be immediately invoked and dispatch
'ed, for this pattern to work.