Describe the applyMiddleware function in Redux.
Last Updated :
13 Feb, 2024
`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:
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
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
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
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
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
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
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:
Output
Share your thoughts in the comments
Please Login to comment...