Before we talk about the principles of Redux middleware, how does Redux handle network request data before it uses middleware

There are several stages:

1. Invoke the DidMount lifecycle in the component to make an asynchronous request

2. After the data is obtained, it is added to the action and sent to the reducer for processing through dispatch

3. Finally change the state in store

This approach has certain disadvantages:

1. Asynchronous code for network requests must be placed into the component’s lifecycle to do this

2. The data requested by the network also belongs to our state management, and a better way would be to hand it over to Redux for management;

Therefore, it is best to put the request network data before reducer and after action. Here comes the concept of middleware and uses a function to intercept actions.

Through a visual story to tell the principle of middleware.

On the React continent there was a kingdom called Redux, and the ruler of Redux was called Store. Store has the right to dispatch in charge of the state of all its subjects, but Dispatch can only order the state according to the way of the object. Since the store’s dispatch is too large and single, many people have a little idea. A wise man wants to see when the dispatch will execute the power and what effect will be generated after the execution. He uses the following methods:

First, necessary conditions: Store and Action

import store from './store/index.js';
import {  addAction, subAction} from './store/actionCreators.js';
Copy the code

The thing you want to do before and after Dispatch is called dispatchAndLogging

Function dispatchAndLogging(action) {console.log(" Dispatching before -- -- ", action); store.dispatch(action); Console. log(" after dispatch --new state:", store.getState()); }Copy the code

Three, how to achieve? Since the Store dispatch is all-powerful, I disguised myself as store.dispatch

Function dispatchAndLogging(action) {console.log(" Dispatching before -- -- ", action); store.dispatch(action); Console. log(" after dispatch --new state:", store.getState()); } store.dispatch = dispatchAndLogging; (Disguise what you want to do as store.dispatch)Copy the code

Four,

During execution, it is discovered that there is no real dispatch authority (because the dispatch here is fake)

Solution: Secretly make a backup copy of dispatch’s power stamp

const next = store.dispatch; Function dispatchAndLogging(action) {console.log(" before dispatch -- Dispatching dispatching action:", action); next(action); Console. log(" after dispatch --new state:", store.getState()); // Use the real dispatch to exercise power console.log(" after dispatch --new state:", store.getstate ()); } store.dispatch = dispatchAndLogging; (Disguise what you want to do as what you want to do at Store. dispatch)Copy the code

Five, so completed the prototype of middleware.

The man saw Dispatch’s past life through a disguise and excitedly told the others the trick. One of them, Thunk, was particularly shocked and thought that if you could disrupt dispatch this way, why not put network requests before and after Dispatch as well?

However, there is still a problem. Although store.dispatch has great power, it can only use the method of passing objects to exercise power, while requesting network data requires a transfer function.

Solution: Since you can only resolve objects with store.dispatch, I’ll thunk functions for you

function patchThunk(store) 
{  
const next = store.dispatch; 
function dispatchAndThunk(action) 
{
if (typeof action === "function") {
action(store.dispatch, store.getState)
//thunk伪装store.dispatch去执行函数相关操作  
} else {
next(action);
//执行完函数后,接着拿着真正store.dispatch的印章去执行对象    
}  
} 
store.dispatch = dispatchAndThunk;}
Copy the code

The upshot: Over time, this method spread throughout the Kingdom of Redux, with various people using various disguises to achieve their goals. Store, the redux ruler, was taken aback by the news. In order to consolidate the form of the kingdom, he recruited these pretenders as applyMiddlewares, distributing power to middleware, each of which could do something before or after store.dispatch, The final action decision rests with the Store dispatch.

function patchLogging(store) { const next = store.dispatch; Function dispatchAndLogging(action) {console.log(" Dispatching before -- -- ", action); next(action); Console. log(" after dispatch --new state:", store.getState()); } return dispatchAndLogging; } function patchThunk(store) {const next = store.dispatch; function dispatchAndThunk(action) { if (typeof action === "function") { action(store.dispatch, store.getState) } else { next(action); } } return dispatchAndThunk; } patchLogging(store); patchThunk(store); function applyMiddlewares(... middlewares) { middlewares.forEach(middleware => { store.dispatch = middleware(store); })} applyMiddlewares(patchLogging, patchThunk);Copy the code

Ps: The above code and pictures are from the React course materials.