Reputation: 6253
I think I am missing a fundamental piece of understanding here. I am aware that in order for an action to be created and thus set off the redux chain of events, the action creator must be invoked using dispatch
.
However, when we have a redux-thunk which returns a function which will call dispatch
on our action creator, why must the redux-thunk also be called with dispatch
?
For example take the following redux-thunk:
function savePerson(person: Person) {
return async (dispatch: any) => {
delete person.cars;
let newPerson = await axios.post('/api/people/addPeron', person);
dispatch(addPersonSuccess(person));
}
}
Calling this savePerson function without dispatch
does not set off the redux flow, and I don't understand why considering the function it returns calls our action creator with dispatch
. Can anybody clarify what I seem to be missing here?
Upvotes: 4
Views: 320
Reputation: 5488
All redux middleware follows the same general layout:
const middleware => store => next => action => next(action);
Why must the redux-thunk also be called with
dispatch
?
Like you correctly pointed out in your first paragraph, for an action/thunk to be evaluated by the redux middleware chain, it must be dispatch
ed by the calling code.
I think the misunderstanding comes in here:
"...when we have a redux-thunk which returns a function which will call dispatch on our action creator...".
While it is correct that the returned function dispatches an action, it is only half the story. Technically, you are dispatching twice: first savePerson
and later addPersonSuccess
. The former being a thunk and the latter, most likely, being a plain action.
Now, let's consider the current redux-thunk
source code:
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
...
export default thunk;
Once you dispatch savePerson
, the middleware recognizes your action as a function. It then injects dispatch
as the first argument to later allow dispatching of other actions. Up until now, dispatch
has not been invoked on your addPersonSuccess
action. Only after your asynchronous call to add a person will the dispatch be called on addPersonSuccess
.
I like to think of this as passing the redux context along in the thunk (dispatch, getState, etc).
ReferencesUpvotes: 2