Detailed explanation of Redux applymeddleware method in react practice

Time:2021-11-29

Mode of use

const store = applyMiddleware(...middlewares)(createStore)(reducer, initialState)

Source code version 0.14.0

function applyMiddleware() {
    //1
  for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
    middlewares[_key] = arguments[_key];
  }
  //2
  return function (createStore) {
      //3
    return function (reducer, preloadedState, enhancer) {
      //4
      var store = createStore(reducer, preloadedState, enhancer);
      var _dispatch = store.dispatch;
      var chain = [];
      //5
      var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
      //6
      _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);

      return _extends({}, store, {
        dispatch: _dispatch
      });
    };
  };
}

The applymiddleware method mainly encapsulates the dispatch method of redux

principle

const _dispatch = store.dispatch;
store.dispatch = function (action) {
  Console.log ('enhanced features');
  _dispatch(action);
  Console.log ('enhanced features');
}

The principle is very simple, that is, replace the store dispatch with a new function with enhanced function but with the function of dispach. Please enter the code
The principle is very similar to the decorator pattern in Java design pattern, which aims to enhance functions, but does not change the interface

Next, the applymiddleware function is analyzed in detail

1. Code / / 1

for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
    middlewares[_key] = arguments[_key];
}

The parameters in the first frame number (… Middlewares) can be multiple middleware (M1, M2, m3) or an array of middleware
So here, all parameters are taken out and put into the middlewares array by traversing the arguments attribute of the JS function

2. Code / / 2 / / 3

The applymiddleware function is actually a coriolised function,
currying (currying) is to transform a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the original function),
And return a new function that accepts the remaining parameters and returns the result

Here are several keywordsMultiple parameters Single parameter Returns the function that accepts the remaining parameters Return results
//Examples

function count(a,b,c) {
    return a+b+c;
}
count(1,2,3);

We can see that count accepts multiple parameters, here are three. Finally, the calculation result is returned. Next, we will colize it

function count(a) {
    return function(b) {
        return function(c) {
            return a+b+c;
        }
    }
}
count(1)(2)(3);

We can see the difference is that after coriolisation, the function only accepts one parameter and returns the function that accepts the remaining parameters, so it needs to be called multiple times

3. / / code 4

var store = createStore(reducer, preloadedState, enhancer);
var _dispatch = store.dispatch;
var chain = [];

Three things have been done here,1Create a store with reducer,2var _ dispatch = store.dispatch; Put the original
The dispatch method is saved, because we need to overwrite the dispach later, but we need to use the function of the original dispatch, so we save it
3var chain = []; Our middleware is also a cored function. This array is used to save the first parameter accepted by the middleware
Function returned after

4. / / code 5

var middlewareAPI = {
    getState: store.getState,
    dispatch: function dispatch(action) {
      return _dispatch(action);
    }
};
chain = middlewares.map(function (middleware) {
    return middleware(middlewareAPI);
});

The middlewareapi object has two members, getstate and dispatch, which we will use in the middleware
So we need to pass them to the middleware and call the middlewares. Map method. Middlewares is an array and the map method
Accept a function. The first parameter of this function is the member of the middlewares array. We will traverse it when we call the map method
The middlewares array passes each of its members to the member handler, and finally returns a value returned by the handler
Through the above code, we can use getstate and dispatch in the middleware

5. / / code 6

_dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);
return _extends({}, store, {
        dispatch: _dispatch
});

What we do here is to enhance dispatch and replace the dispatch in the store,
The middleware will be called in the replaced dispach, and we see the return value_ Extensions is a function that receives the store and after enhancement
Yes_ Dispatch, which is used to replace its own dispatch method