Blog>
Snippets

Future-Proofing Middleware through Higher-Order Functions

Showcase a higher-order function approach to writing Redux middleware that allows for abstraction and code reuse, making it easier to update and extend middleware functionality as application requirements evolve.
const createLoggerMiddleware = (logger = console.log) => store => next => action => {
  logger('dispatching', action);
  let result = next(action);
  logger('next state', store.getState());
  return result;
};

// Usage:
// const loggerMiddleware = createLoggerMiddleware();
// applyMiddleware(loggerMiddleware);
Defines a higher-order function that creates a logging middleware. It takes a logger function as an argument, defaulting to console.log, allowing for a custom logger to be injected. As requirements change, the logger can be replaced without altering the middleware's internal structure.
const createAsyncActionMiddleware = extraArgument => store => next => action => {
  if (typeof action === 'function') {
    return action(store.dispatch, store.getState, extraArgument);
  }
  return next(action);
};

// Usage:
// const thunkMiddleware = createAsyncActionMiddleware(apiService);
// applyMiddleware(thunkMiddleware);
Creates a middleware for handling async actions, known as thunks. This higher-order function allows us to pass an extra argument (e.g., an API service) to the action creator. The middleware can then be effortlessly adjusted by passing in different extra arguments as external dependencies evolve.
const createActionValidatorMiddleware = schemaValidator => store => next => action => {
  const validationResult = schemaValidator(action);
  if (validationResult.valid) {
    return next(action);
  }
  throw new Error('Invalid action schema');
};

// Usage:
// const validatorMiddleware = createActionValidatorMiddleware(actionValidationSchema);
// applyMiddleware(validatorMiddleware);
Provides a middleware for action schema validation using a higher-order function to inject a schemaValidator. It checks if an action complies with the provided schema before passing it along. This pattern allows for easy updates to the validation logic or schema by tweaking the schemaValidator function.