Impure and asynchronous; but still redux In my article, , I highlighted the simplicity of a reducer and the complexity that arises from the interaction between these reducers. And as we saw there, the sole purpose of a reducer is . Redux Lifecycle redux state manipulation What about actions? Who performs action manipulation? Middleware Borrowing words from , a middleware: redux.js.org is not a fundamental part of the Redux but is considered useful enough to be supported right in the core architecture is the suggested way to extend Redux with custom functionality and can be composed in a chain provides a third-party extension point between dispatching an action, and the moment it reaches the reducer has the same plural form (i.e. middlewares is not a word) almost always looks like: const middleware = (mwApi) => (next) => (action) => {// do something}; This is just the curried form of a function that takes in 3 arguments and so I will write it in its original form: function middleware(mwApi, next, action) {// do something} Note : curry? confused? you might want to have a look at this 10 min read Middleware Input A middleware takes three arguments: mwApi An object with two methods — and — that is sometimes written as the ‘store’ in the middleware definition when it’s not. Nonetheless, we can use to get the complete state tree from the store and call with some action to ‘inject’ actions in the redux lifecycle. getState() dispatch() getState() dispatch() next As stated above, middleware can be composed in a chain. This composition is done by passing middleware functions to and connecting the returned store enhancer to the redux store. applyMiddleware The provided middleware create a pipeline of callbacks where the next middleware in the chain becomes the argument of a middleware. next The final middleware in the pipeline receives the store’s . This way, there is a single standard way to extend dispatch in the ecosystem. dispatch In other words: function (mwApi, next, action) {...}function (mwApi, next, action) {...}...function (mwApi, next, action) {...} mw1 mw2 mw_N_ const = createStore(rootReducer,applyMiddleware(mw1, mw2, ..., mw_N_)) store //> mw1.next === mw2//> mw2.next === mw3//> ...//> mw_N_.next === store.dispatch action An action object injected into the redux lifecycle by: store’s own dispatch method (after passing all middleware) a middleware directly calling mwApi.dispatch Once the action reaches the after passing the final middleware in the pipeline, it is dispatched to the reducers. dispatch() Middleware Output Middleware don’t return anything since they form a callback pipeline and their return values are completely ignored. Just FYI, nobody’s stopping you from returning a value of your liking from a middleware. Middleware Sideways Sometimes, we can choose not to call in certain conditions to stop the flow of down the pipeline and into the reducers. This can be thought of as dumping an into a “metaphorical” sink. next() action action function (mwApi, next, action) {// just don't call } mw next(action) A middleware can also modify the current action before passing it on or pass some other action in its place. function (mwApi, next, action) {if (action.type === FOO) {action.payload.push(foo)} mw if (action.type === BAR) {action = barAction()} next(action)} Even crazier, with access to the method, a middleware can decide to “translate” an into a series of other actions. dispatch() action function (mwApi, next, action) {if (action.type === FOO) {mwApi.dispatch(firstFooAction())mwApi.dispatch(secondFooAction())mwApi.dispatch(notFooAction())} else {next(action)}} mw Final Thoughts In redux, middleware are a force to reckon with. They offer us tremendous flexibility for action manipulation but they also carry heavy implicit risks. One misplaced call is all it takes to shutdown your entire app. next() We can easily abstract away complex behaviour in our apps, like: action logging async requests handling cookies persisting data analytics transmit data over websockets etc… Start exploring the different middleware by visiting the on the official redux website. Ecosystem page