Skip to content
Related Articles

Related Articles

What is the use of middleware Redux thunk ?

View Discussion
Improve Article
Save Article
  • Last Updated : 14 May, 2022

Redux is a state management tool, which is used to store the state of different variables in our react application. It makes complex react applications easier by centralizing the application state. You can learn more about redux here. Redux supports middleware, and middleware functions run between dispatching an action and the moment it reaches the reducer. Redux middlewares can be used for logging, routing, asynchronous actions, etc.

For the scope of this tutorial, we will focus on a redux middleware called thunk. It allows us to return functions instead of objects from redux actions. Plain redux doesn’t allow complex logic inside action functions, you can only perform simple synchronous updates by dispatching actions. This middleware extends its ability and lets you write complex logic that interacts with the store. Thunk doesn’t interfere with the action until it returns a function. Thunk allows us to dispatch actions manually, which gives us the power to incorporate some logic or run some asynchronous code before dispatching an action. The function returned from action is called a thunk function which is called with two arguments : 

1. dispatch: It is a method used to dispatch actions, that can be received by reducers. 
2. getState: It gives access to store inside the thunk function.

A thunk function may contain any arbitrary logic, sync, or async, and can call dispatch or getState at any time. Before moving any further let’s understand the difference between the flow of redux with and without thunk.

Redux flow without thunk : 

 

Redux Flow with Thunk: 

 

Setup of Redux with Thunk:

Step 1: To set up redux with thunk, we will start by creating a react application, and install all the required dependencies. Run the following command to create a new react application.

npx create-react-app myapp

Step 2: Open your project in a code editor and install all the required packages: redux, react-redux & redux-thunk.

npm install redux react-redux redux-thunk

Now, create two files inside the root directory: actions.js & reducers.js.

Following is the updated project structure: 

 

Now we’ll create some actions and reducers to interact with the store based on those actions. 

We’ll create two actions, deleteData is a normal action creator, it doesn’t include any complex or async logic hence thunk will not interfere in its execution. The addData action creator contains async logic, hence we return a function (thunk function) that calls dispatch when data is fetched from the API. (For this tutorial we are using JSONPlaceholderAPI you can learn more about it here.) Then in the app.js file we add buttons to dispatch the actions and display the fetched data.

/action.js




// This is a synchronous action, hence
// thunk will not interfere.
export const deleteData = ()=>{
    return ({
        type : 'DELETE_DATA'
    })
}
  
// This function includes some async logic,
// hence we can dispatch action manually
export const addData  = ()=>{
  
    // Thunk Function
    return async (dispatch,getState)=>{
  
        // Fetching results from an API : asynchronous action
        const response = await fetch(
        const data = await response.json();
  
        // Dispatching the action when async
        // action has completed.
        dispatch({
            type : 'ADD_DATA',
            payload : data
        });
    }
}


Here we’ll create reducers to update the state based on those actions, and export the reducers to create a state. 

/reducers.js




const { combineReducers } = require("redux");
  
const INITAL_STATE  = {
    todo : null
}
  
const dataReducer = (state=INITAL_STATE, action)=>{
    switch(action.type) {
        case 'ADD_DATA' : return {...state, todo : action.payload};
        case 'DELETE_DATE' : return INITAL_STATE;
        default : return state;
    }
}
  
const reducers = combineReducers({
    data : dataReducer
})
  
export default reducers


We will first cleanup some boilerplate code and then create a store with middleware thunk. Provider function centralizes the state in our whole application.

/index.js




import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
  
import { applyMiddleware, createStore } from "redux";
import reducers from "./reducers";
import thunk from "redux-thunk";
import { Provider } from "react-redux";
  
  
// Create store with the reducers and
// apply thunk as a middleware
const store = createStore(reducers, applyMiddleware(thunk));
  
const root = ReactDOM.createRoot(
    document.getElementById("root"));
  
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);


We begin by importing all of the actions & hooks, then use the useDispatch hook to dispatch actions and the useSelector hook to access data in the store. We’ve added two buttons to call the handler functions handleAddData and handleDeleteData, which dispatch their respective actions.

/app.js




import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { addData, deleteData } from "./actions";
const App = () => {
  const dispatch = useDispatch();
  // Selects the state value from the store.
  const todo = useSelector((state) => state.data.todo);
  // Dispatches action to add the data
  const handleAddData = ()=>dispatch(addData());
  // Dispatches action to delete the data.
  const handleDeleteData = ()=>dispatch(deleteData());
  return (
    <div>
      <button onClick={handleAddData}>Add Data</button>
      <button onClick={handleDeleteData}>Delete Data</button>
  
      {todo && <div>{JSON.stringify(todo)}</div>}
    </div>
  );
};
  
export default App;


Output: 

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!