# Redux Middleware in React

## Redux Middleware in React

Redux Middleware allows us to intercept every action sent to the reducer so that we can make changes to the action or cancel the action.&#x20;

Middleware helps us with logging, error reporting, making asynchronous requests, and a whole lot more.

Redux Middleware consists of 3 functions `store` `next` and `action` chained together and get called in this order.&#x20;

```jsx
const loggingMiddleware = function(store) {
  // Executed when applyMiddleware is called so that our middleware can have access to the store

  return function(next) {
    // next is the following action to be run after this middleware

    return function(action) {
      // finally, this is where our logic lives for our middleware.
    }
  }
}

```

## Custom Middleware Example&#x20;

A custom Middleware that logs previous and next state in the browser console.

{% tabs %}
{% tab title="store.js" %}

```jsx
// Importing the 'legacy_createStore' function from Redux
import { applyMiddleware, legacy_createStore as createStore } from "redux";

// Importing the root reducer for the Redux store
import rootReducer from "./rootReducer";

// Create a custom middleware
const myLogger = (store) => (next) => (action) => {
  // Get action type
  console.log(`Action: ${JSON.stringify(action)}`);

  // Get current state
  console.log(`Before: ${JSON.stringify(store.getState())}`);

  // Get updated state
  const updatedState = [action].reduce(rootReducer, store.getState());
  console.log(`After: ${JSON.stringify(updatedState)}`);

  // Pass action so that state can be updated
  return next(action);
};

// Creating the Redux store using the 'createStore' function and putting a custom middleware
const store = createStore(rootReducer, applyMiddleware(myLogger));

// Exporting the created store as default
export default store;

```

{% endtab %}
{% endtabs %}

We can combine multiple middlewares together.

```jsx
// Combining two custom middlewares
const store = createStore(rootReducer, applyMiddleware(myFirstLogger, mySecondLogger));
```
