Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do redux-thunks need to be bound to dispatch?

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?

like image 524
Chaim Friedman Avatar asked Oct 15 '25 18:10

Chaim Friedman


1 Answers

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 dispatched 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).

References
  • http://redux.js.org/docs/advanced/Middleware.html
  • https://github.com/gaearon/redux-thunk
like image 145
Mario Tacke Avatar answered Oct 18 '25 08:10

Mario Tacke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!