bakrall
bakrall

Reputation: 633

How does action creator which is a thunk receive a store's dispatch method?

I am learning redux and there is one thing puzzling me regarding the internal logic - how does a thunk receive dispatch as argument if a thunk is an argument to dispatch and not vice versa? Here is a sample code:

I am creating an action creator which is a thunk (it does not return an action itself but another function which eventually returns the action). I am defining it to receive dispatch function as argument, like this (code is simplified to serve as example):

export const fetchPosts = () => {
   return async (dispatch) => {
     const response = await fetch('some url');

     dispatch({type: 'FETCH_POSTS', payload: response});
   }
}

Then I use this thunk in App.js file, when I am getting a dispatch function from 'react-redux':

import { useDispatch } from 'react-redux';
import { fetchPosts } from './store/posts-actions';

function App() {
  const dispatch = useDispatch();

  useEffect(() => {
      dispatch(fetchPosts());
  },[dispatch]);

  ...
}

I am not passing dispatch as an argument to fetchPosts(). I am passing fetchPosts() to dispatch. And this is the part that I don't understand.

How does fetchPosts receive dispatch as argument if fetchPosts is an argument to dispatch and not vice versa?

Upvotes: 1

Views: 49

Answers (1)

markerikson
markerikson

Reputation: 67577

This is covered in the Redux docs pages on Writing Logic with Thunks and Redux Fundamentals, Part 6: Async Logic and Data Fetching.

The Redux thunk middleware looks for any time that a function gets passed into dispatch, intercepts that function, and then calls it with (dispatch, getState) as arguments:

// standard middleware definition, with 3 nested functions:
// 1) Accepts `{dispatch, getState}`
// 2) Accepts `next`
// 3) Accepts `action`
const thunkMiddleware =
  ({ dispatch, getState }) =>
  next =>
  action => {
    // If the "action" is actually a function instead...
    if (typeof action === 'function') {
      // then call the function and pass `dispatch` and `getState` as arguments
      return action(dispatch, getState)
    }

    // Otherwise, it's a normal action - send it onwards
    return next(action)
  }

Upvotes: 0

Related Questions