petu
petu

Reputation: 13

Why I can execute dispatch() method without using an instance of a Redux store(store.create())?

I have been using Redux on some of my projects by following some tutorials, in order to make API calls(write action creators that return a function instead of an action) we use redux-thunk.

I don't understand why inside this action creators functions I can run dispatch() without having to use an instance of the store store.dispatch()?

Example on the redux documentation:

import { createStore } from 'redux'
const store = createStore(todos, ['Use Redux'])

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  }
}

store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))

Tutorial Code:

const loadRockets = () => async (dispatch) => {
  const res = await fetch(URL);
  const data = await res.json();
  const state = data.map((rocket) => ({
    id: rocket.id,
    name: rocket.rocket_name,
    image: rocket.flickr_images[0],
    type: rocket.rocket_type,
    description: rocket.description,
    reserved: false,
  }));
  dispatch({ type: LOAD, state });
};

Upvotes: 0

Views: 298

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 85032

You can do that because the redux-thunk middleware is designed to work that way. If you dispatch a function, redux-thunk will call that function and pass the dispatch function in to you. If you're curious, here is the code where they implement that (in particular, the return action(dispatch, getState, extraArgument) part):

function createThunkMiddleware<
  State = any,
  BasicAction extends Action = AnyAction,
  ExtraThunkArg = undefined
>(extraArgument?: ExtraThunkArg) {
  // Standard Redux middleware definition pattern:
  // See: https://redux.js.org/tutorials/fundamentals/part-4-store#writing-custom-middleware
  const middleware: ThunkMiddleware<State, BasicAction, ExtraThunkArg> =
    ({ dispatch, getState }) =>
    next =>
    action => {
      // The thunk middleware looks for any functions that were passed to `store.dispatch`.
      // If this "action" is really a function, call it and return the result.
      if (typeof action === 'function') {
        // Inject the store's `dispatch` and `getState` methods, as well as any "extra arg"
        return action(dispatch, getState, extraArgument)
      }

      // Otherwise, pass the action down the middleware chain as usual
      return next(action)
    }
  return middleware
}

https://github.com/reduxjs/redux-thunk/blob/master/src/index.ts#L30

Upvotes: 2

Related Questions