How does the inner function get the 'dispatch' parameter?

Viewed 117

I am new to React-Redux!

But I have a problem.

How does the inner function (async dispatch) receive the dispatch() parameter?

GetCurrentUserInfo Action Creator function:

export const getCurrentUserInfo = () => async dispatch => {
  const response = await axios.get('/api/users/me')

  dispatch({
    type: userActions.SET_CURRENT_USER_INFO,
    users: response.data.data
  })

  return response.data.data
}

How getCurrentUserInfo is called:

export const AuthGuard = connect(
  state => ({
    currentUserSlug: state.session.currentUser
  }),
  dispatch => ({
    authOrRedirect: () => {
      return dispatch(getCurrentUserInfo()).catch(() => {
        history.replace('/login')
      })
    }
  })
)(AuthGuardComponent)

getCurrentUserInfo() does not receive any parameters, but is it because it is enclosed in dispatch(getCurrentUserInfo())?

1 Answers

getCurrentUserInfo() returns a function that expects one parameter dispatch. You need to call that returned function and pass the dispatch parameter to it:

export const AuthGuard = connect(
  state => ({}),
  dispatch => ({
    authOrRedirect: () => {
      return getCurrentUserInfo()(dispatch).catch(() => {
        history.replace('/login')
      })
    }
  })
)(AuthGuardComponent)

For example:

Obviously you could write the getCurrentUserInfo() like this:

const getCurrentUserInfo = function(){  // create getCurrentUserInfo dispatcher
  return async function(dispatch){
    // ...
  };
}

The dispatchProp could be written like this:

export const AuthGuard = connect(
  state => ({}),
  dispatch => ({
    authOrRedirect: () => {
      const getUserInfoDispatcher = getCurrentUserInfo();  // create dispatcher
      getUserInfoDispatcher(dispatch).catch(() => {        // call dispatcher
        history.replace('/login')
      })
    }
  })
)(AuthGuardComponent)

common patterns

obviously you are confused about these two patterns, which you might have seen somewhere:

  • A: getCurrentUserInfo()(dispatch): call a "dispatching function"
  • B: dispatch(getCurrentUserInfo()): dispatch an "action"

(A) works in your case, because getCurrentUserInfo() returns a "dispatching function" (not an official term), i.e. a function that calls dispatch( someAction ).
getCurrentUserInfo()(dispatch) invokes this "dispatching function".

(B) is a pattern that would be used if getCurrentUserInfo() would be an "action creator" (which it isn't in your case), i.e. a function that returns an "action", like { type: ..., users: ... }.

Related