How Redux Thunk Works Under The Hood

Redux Thunk is a middleware that allows you to write action creators that return a function instead of an action. This function can contain asynchronous or complex synchronous logic. The way Thunk connects to your overall app and how reducers access data from a thunk can be understood in a few steps:

Connection of Thunk to the Overall Application

  1. Store Configuration: When setting up your Redux store, you include Redux Thunk (or it's included by default if you're using Redux Toolkit). This middleware extends the store's abilities, allowing it to accept functions (thunks) in addition to regular action objects.

     import { configureStore } from '@reduxjs/toolkit';
    
     const store = configureStore({
       reducer: {
         // Your reducers
       },
       // Middleware including thunk is configured here
     });
    
  2. Dispatching Thunks: In your components or wherever you dispatch actions, you can now dispatch thunks. These thunks can perform asynchronous operations like API calls.

     import { useDispatch } from 'react-redux';
    
     const MyComponent = () => {
       const dispatch = useDispatch();
    
       const handleLoadData = () => {
         dispatch(myAsyncThunk());
       };
    
       // JSX and other component logic
     };
    
  3. Thunks Execution: When a thunk is dispatched, Redux Thunk middleware intercepts it. The thunk is a function that receives the dispatch and getState functions as arguments, allowing it to dispatch other actions or access the current state.

How Reducers Access Data from a Thunk

  1. Dispatching Actions from Thunks: A thunk usually dispatches actions based on the result of its asynchronous or complex logic. For instance, in an API call, it might dispatch one action when the call starts, another if the call is successful, and another if the call fails.

     const myAsyncThunk = () => async dispatch => {
       dispatch(startLoadingAction());
       try {
         const data = await fetchData();
         dispatch(fetchSuccessAction(data));
       } catch (error) {
         dispatch(fetchFailureAction(error));
       }
     };
    
  2. Reducers Handling Actions: The reducers in your application respond to these dispatched actions. Reducers are pure functions that take the current state and an action as arguments and return a new state. When a reducer receives an action dispatched from a thunk (like fetchSuccessAction), it processes the action's payload and returns the updated state.

     const myReducer = (state = initialState, action) => {
       switch (action.type) {
         case 'FETCH_SUCCESS':
           return {
             ...state,
             data: action.payload,
             loading: false,
           };
         // Other cases
       }
     };
    
  3. State Update: Once the reducer processes the action, the state of the application is updated. Components connected to the Redux store can then re-render based on this new state.

Summary

In summary, Redux Thunk acts as a bridge between asynchronous or complex logic and the Redux store. It allows you to dispatch functions (thunks) that can handle this logic and then dispatch regular actions based on the outcome. Reducers respond to these actions as they would to any other action, updating the state accordingly. The components in your application, in turn, reflect these state changes, providing a seamless integration of asynchronous processes into the Redux state management workflow.