Middleware fica entre enviar uma action e a action chegar ao reducer, permitindo que você intercepte actions para lidar com side effects (chamadas assíncronas de API, logging) — que reducers não podem fazer porque devem permanecer puros. Thunks são o middleware mais comum, permitindo lógica assíncrona.
Como middleware se encaixa
dispatch(action) → [ middleware 1 → middleware 2 → ... ] → reducer → store
(can inspect, modify, delay, or stop actions; do side effects)
