reactjsreduxredux-thunk

How does a react action have access to dispatch?


In my react project I have an actions file that looks like this:

const startLoad = () => async (dispatch) => {
  dispatch({
    type: CONTENT_LOAD,
  });
};

// Get all content
export const getContents = () => async (dispatch) => {
  dispatch(startLoad());
  // some more code...
};

So in this example, I know that dispatch is coming from the middleware and getContents has access to it because it was mapped using mapDispatchToProps. So I am assuming when getContents is called, its really called like this -> dispatch(getContents) but can this be replicated in plain JavaScript so I can see what is really going on? If I am wrong about why getContents has access to dispatch please let me know.

For example, how isstartLoad able to use dispatch just because dispatch called startLoad? I have noticed that it will also work if I call it like this: dispatch(startLoad(dispatch));.

Passing dispatch in to startLoad actually makes more sense to me so I don't get why that isn't required.

Edit: this is the closest example I could come up with on my own.

const fun = () => (fun2) => {
  fun2();
}

const fun2 = () => {
  console.log('hello');
}

fun()(fun2);

Solution

  • So I am assuming when getContents is called, its really called like this -> dispatch(getContents) but can this be replicated in plain JavaScript so I can see what is really going on? If I am wrong about why getContents has access to dispatch please let me know.

    redux-thunk has quite simple implementation

    function createThunkMiddleware(extraArgument) {
      return ({ dispatch, getState }) => (next) => (action) => {
        if (typeof action === 'function') {
          return action(dispatch, getState, extraArgument);
        }
    
        return next(action);
      };
    }
    

    As you can see it checks if action is a function.

    And bonus, if you like you can get the whole state and extra argument in params following dispatch

    For example, how isstartLoad able to use dispatch just because dispatch called startLoad? I have noticed that it will also work if I call it like this: dispatch(startLoad(dispatch));.

    It looks like middleware also handles above case.