intermediate

Middleware

Intercept dispatch for async workflows, logging, analytics, side effects, and cross-cutting policies.

Middleware wraps dispatch: `store => next => action => {}`. It can log, delay, transform, or trigger async work before/after reducers run. The chain ends when `next(action)` reaches the reducer.

Common uses: redux-thunk (functions dispatched as async actions), custom analytics, auth token injection, crash reporting. RTK `configureStore` includes thunk by default.

					const logger = (store) => (next) => (action) => {
  console.log('dispatching', action);
  const result = next(action);
  console.log('next state', store.getState());
  return result;
};
				

Prefer RTK Query or listener middleware for data fetching over hand-rolled thunk spaghetti. Keep middleware focused — not a second application layer.

The trade-off is cross-cutting async and logging in one pipeline versus harder-to-follow dispatch chains.

On interviews: where async belongs (thunk vs RTK Query vs component effect).

Common pitfalls: infinite dispatch loops, middleware ordering surprises, and business logic duplicated across many thunks.

Checklist:

  • Middleware for cross-cutting dispatch concerns.
  • Call next(action) unless swallowing intentionally.
  • RTK Query for server cache lifecycle.
  • Avoid heavy orchestration in middleware.