Out of the box, Redux may meet most of your app’s state management needs. But every project is different, and so Redux provides some ways to customize its behavior. One of the ways we can customize Redux is by adding middleware.
You may be familiar with middleware from experiences working with other frameworks. As the name suggests, middleware is the code that runs in the middle—usually between a framework receiving a request and producing a response. Middleware is a powerful tool for extending, modifying, or customizing a framework or library’s default behavior to meet an application’s specific needs.
In Redux, middleware runs between the moment when an action is dispatched and the moment when that action is passed along to the reducer. By this point you’re familiar with the way data flows through Redux: actions are dispatched to the store, where they are processed by reducers that produce new state; that new state becomes accessible to all the components that reference it, causing those components update. We’ve rendered that flow in the included diagram, and added middleware to help you see where and how it comes into play.
Middleware intercepts actions after they are dispatched and before they are passed along to the reducer. Some common tasks that middleware perform include logging, caching, adding auth tokens to request headers, crash reporting, routing, and making asynchronous requests for data. You can add any of these functionalities to your apps by using popular open-source middleware. Of course, you can also write your own middleware to solve problems that are specific to your application and its architecture.
To make asynchronous requests in our recipe app, we’re using
redux-thunk, a middleware for handling asynchronous requests. There are several popular middleware that make asynchronous functionality compatible with Redux; we chose this one because it’s one of the most widely-employed, and it is included with Redux Toolkit by default. In subsequent exercises, we will walk through how
redux-thunk makes asynchronous requests possible; for now, you should just understand where it sits in Redux’s data flow.
Before moving on, make sure you understand how middleware fits into Redux’s data flow, depicted here for you in an animated diagram. In a project without middleware, Redux immediately passes dispatched actions to the store’s reducer. But when we add middleware to a Redux project, Redux passes dispatched actions to the middleware before passing them to the reducers.
Here are some focusing questions to think about during this lesson: What step in Redux’s data flow happens right before middleware runs? What step in the Redux data flow happens right after middleware runs?