Open In App

Describe the applyMiddleware function in Redux.

Last Updated : 13 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

`applyMiddleware` is a function provided by Redux that improves the capability of the store by applying middleware to the dispatch process. Middleware if you talk about it, is a piece of code that intercepts actions before they reach the reducer, allowing you to modify the actions before they reach the reducer or to perform additional logic, such as asynchronous API calls.

Prerequisites

Approach 1:

In this approach, `applyMiddleware` is directly used within the `createStore` function. `thunk` is a middleware here.

Syntax:

const store = createStore(
rootReducer,
applyMiddleware(thunk)
);

Approach 2:

Combining multiple middlewares by using `applyMiddlware` in conjunction with compose. In this approach, multiple middlewares are combined using `applyMiddleware` and then composed using `composeEnhancers`. It allows combining multiple middlewares and enhancers in a single function. `loggerMiddleware` is a custom middleware that we will log the actions and state.

Syntax:

const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
rootReducer,
composeEnhancers(
applyMiddleware(loggerMiddleware, thunkMiddleware)
)
);

Step by Step Implementation of applyMiddleware:

Step 1: Create a react app and enter into it by using the provided commands

npx create-react-app apply-middleware
cd apply-middleware

Step 2: Install required dependencies by using the following command

npm install redux react-redux redux-thunk

Project Structure:

md1

Project Structure

The updated dependencies in package.json file will look like:

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.0",
"react-scripts": "5.0.1",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"web-vitals": "^2.1.4"
}

Step 3: Create a folder `store` in `src` directory of the react app. Add three files (store.js, reducer.js, actions.js)

Step 4: Write `actions.js` file. Here we will export three actions and action types.

Step 5: Write the `reducer.js` file. In this article, we want to maintain the state of a counter on increment and decrement. So, we have written a reducer to change counter state.

Step 6: Create a `middlewares` folders at `src` and further create a file `loggerMiddleware.js`

Step 7: Write `store.js`

Step 8: Update `src/index.js` to include Provider Wrapper with store as props.

Step 9: Write `src/App.js` file

Javascript




// actions.js
 
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const RESET = 'RESET';
 
export const increment = () => {
    return { type: INCREMENT };
};
 
export const decrement = () => {
    return { type: DECREMENT };
};
 
export const reset = () => {
    return { type: RESET };
};


Javascript




// reducer.js
 
import {
    INCREMENT,
    DECREMENT, RESET
} from "./actions";
const initialState = {
    count: 0
};
 
const counterReducer =
    (state = initialState, action) => {
        switch (action.type) {
            case INCREMENT:
                return {
                    ...state,
                    count: state.count + 1
                };
            case DECREMENT:
                return {
                    ...state,
                    count: state.count - 1
                };
            case RESET:
                return {
                    ...state,
                    count: 0
                };
            default:
                return state;
        }
    };
 
export default counterReducer;


Javascript




// /middlewares/loggerMiddleware.js
 
const loggerMiddleware =
    store => next => action => {
        console.log('Dispatching:', action);
        const result = next(action);
        console.log('Next State:', store.getState());
        return result;
    };
 
export default loggerMiddleware;


Javascript




// store.js
 
import {
    legacy_createStore as createStore,
    applyMiddleware, compose
} from 'redux';
import rootReducer from './reducer';
import loggerMiddleware
    from '../middlewares/loggerMiddleware';
import { thunk } from 'redux-thunk';
 
const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
 
const store = createStore(
    rootReducer,
    composeEnhancers(
        applyMiddleware(loggerMiddleware, thunk)
    )
);
 
export default store;


Javascript




// index.js
 
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import store from './redux/store';
 
const root =
    ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
        <App />
    </Provider>
);


Javascript




// App.js
 
import React from 'react';
import {
    useSelector,
    useDispatch
} from 'react-redux';
import {
    increment,
    decrement, reset
} from './redux/actions';
 
const App = () => {
    const count =
        useSelector(state => state.count);
    const dispatch = useDispatch();
 
    return (
        <div>
            <h2>
                Counter: {count}
            </h2>
            <button onClick={() => dispatch(increment())}>
                Increment
            </button>
            <button onClick={() => dispatch(decrement())}>
                Decrement
            </button>
            <button onClick={() => dispatch(reset())}>
                Reset
            </button>
        </div>
    );
};
 
export default App;


Steps to run the app:

npm start

Output:

2024-02-0716-50-13-ezgifcom-video-to-gif-converter

Output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads