Parameter-Based Middleware

Let’s have a look at parameter-based middleware that is more generic and allows better usability.

Some middleware might be reusable and support parameters passed during their creation.

For example, consider the nullMiddleware we created in the previous section:

const nullMiddleware = () => next => action => {
  next(action !== null ? action : { type: 'UNKNOWN' });
};

export default nullMiddleware;

The 'UNKNOWN' key is hardcoded into our middleware and will not allow easy reuse in our other projects. To make this middleware more generic, we might want to be able to support arbitrary action types and use the applyMiddleware() stage to specify how we want our middleware to behave:

import { createStore, applyMiddleware } from 'redux';
import reducer from 'reducers/root';
import nullMiddleware from 'middleware/null';

const store = createStore(reduce, applyMiddleware(nullMiddleware('OH_NO'));
};

Here we want our nullMiddleware to dispatch 'OH_NO' instead of the default 'UNKNOWN'. To support this, we must turn our middleware into a “middleware creator”:

const nullMiddlewareCreator = param => () => next => action => {
   next(action !== null ? action : { type: param || 'UNKNOWN' });
};

export default nullMiddlewareCreator;

Instead of returning the middleware directly, we return a function that creates a middleware with embedded custom parameters. This allows complex middleware to function as libraries that can be easily customized when added to the store.

Get hands-on with 1200+ tech skills courses.