Digression: Years ago the last working day is not much, just saw the recent but easy to forget the important knowledge points summed up, after all, good memory is not as bad as the pen, no longer young do not help.
First, put a redux Chinese document on middleware (middleware) official explanation.
Redux Middleware
The concept of middleware is redux from other frameworks and is intended as follows:
Middleware refers to code that can be embedded in a framework to receive requests to produce a response. For example, Express or KOA middleware can complete adding CORS headers, logging, content compression, and so on.
And in the Redux:
Middleware are used to solve different problems, but the concepts are similar. It provides an extension point before the action is initiated to reach reducer. You can use Redux middleware to log records, create crash reports, invoke asynchronous interfaces or routes, and so on.
Both of these references are from official documents. You can see that the middleware in Redux is similar to what is done in other frameworks. is essentially a thought of slicing programming Aspect oriented programming (AOP). business logic and other parts (log, error reporting, etc.) can achieve a good solution to the Lotus root. It can be viewed as an adorner pattern from the design pattern.
usage
Let Newstore = Applymiddleware (Mid1, Mid2, MID3, ...) (CreateStore) (reducer, initialstate);
The following is the source code of Applymiddleware:
Import compose from './compose '
export default function Applymiddleware (... middlewares) {return
createstore =& Gt (... args) => {
Const store = createstore (... args) let
dispatch = () => {
throw new Error (
' Dispatchi ng while constructing your middleware are not allowed. ' +
' other middleware would is applied to this dispatch. '
)
} let
chain = []
const MIDDLEWAREAPI = {
GetState:store.getState,
Dispatch: (... args) => dispatch (... args)
}
chain = Middlewares.map (middleware => Middleware (MIDDLEWAREAPI))
dispatch = Compose (... chain) (Store.dispatch) Return
{
... store,
dispatch
}
}}
The following is the code for a middleware sample (from an official document):
/**
* Records all the initiated action and the resulting new state.
* *
Const LOGGER = store => next => action => {console.group
(action.type)
console.info (' Dispatching ', action ' let result
= Next (action)
Console.log (' Next state ', Store.getstate ())
Console.groupend (Action.type) return result
}
When I looked at the source code, I raised four main questions:
1. Why do you want to pass in CreateStore
2. What is args?
3. The role of Compose
4. Middleware so many functions nested, each incoming parameter is what as well as the role
Through the answers to the above questions, deepened my understanding of the Applymiddleware source code.
Why do you want to pass in CreateStore
The above sentence can be seen to simply create the store. It's just a middleware to wrap it in the deepest part of the Onion.
... what is args?
I unfolded the args to see that it was the standard parameter of the Redux native CreateStore method , which answered the first question on the other.
the role of compose
Compose itself is not a redux-specific concept, but a thought of functional programming. About the introduction of functional programming can refer to Nandashin's fallacy: functional programming approach . I'm only here to talk about compose.
compose in English name thinking Chinese meaning is a combination function, combining several functions in tandem execution, one function output as the input of another function, once the first function begins to execute, the process will be like a domino.
Note: There was a little doubt about compose. Why function arguments in compose are executed from right to left.
It can be seen from the following code. What I see is difficult to describe, understand nature (the parameter arrangement conforms to the reading order, and the order of execution is the opposite).
Let result = Compose (F1, F2, F3, F4) (value);
Equivalent to let result
= F1 (F2 (F3 (value)));
middleware So many function nesting, each incoming parameter is what as well as the function
Make a comparison between the Applymiddleware and the middleware examples:
From the above figure you can draw:
1. Middlewareapi is actually a getstate and Dispach method of the simple version of the store.
2. In middleware, next (action) is to distribute the action, reasonable suspicion is the dispatch of the store, by comparing the code in Applymiddleware to prove this.
To impress, my path is to assume that there is a middleware, and then extend it to multiple:
A middlwware
Source code
Dispatch = Compose (... chain) (Store.dispatch)
//equivalent to
Fnmiddle = fn (MIDDLEWAREAPI);
Dispatch = Fnmiddle (store.dispatch)
//equivalent to
dispatch = FN (MIDDLEWAREAPI) (Store.dispatch)
Commonly used
Store.dispatch (action)
//equivalent to
fn (MIDDLEWAREAPI) (Store.dispatch) (action)
// Exactly corresponds to the three parameters of middleware store, next, action
Multiple middlwware:fn1, fn2
Source code
Dispatch = Compose (... chain) (Store.dispatch)
//equivalent to dispatch= fn1middle
( Store.dispatch)
//Fn1middle = FN1 (MIDDLEWAREAPI) etc.
It's interesting to read here, the first thing to do is Fn2middle (Store.dispatch), and the result is a function of the following. Immediately after Fn1middle ((action) => {}), this action function is the position that occupies the next parameter in FN1. The function does not execute until the action argument is received. Then after receiving the Acton parameters, it is too difficult to continue to use the language description, I tried to draw a picture, I hope in the back to look not to burn a lot of brain.
Fn2middle (Store.dispatch) after execution
(action) => {
....
Next (Action) ...
}
Add one more point:
Let Newstore = Applymiddleware (Mid1, Mid2, MID3, ...) (CreateStore) (reducer, initialstate);
Newstore is formed after inserting the middleware. At this point Newstore.dispatch method is no longer the original Redux Store.dispatch, but in turn into the logic of the middleware, native store.dispatch into the onion model in the innermost.
Dispatch= Fn1middle (Fn2middle (Store.dispatch))
the key to this realization is the Applymiddleware source code the last return value, the ES6 style of the result is added after the dispatch method covers the original Store.dispatch
Export default function Applymiddleware (... middlewares) {return
createstore => (... args) => {
....
. dispatch = Compose (... chain) (Store.dispatch) return
{
... store,
dispatch
}
}}
Comb again more clearly, so burned the brain for half a month to forget, record the significance of the same as Redux-devtool time travel, in the chaos after the operation can also find this piece of beginner's mind.
Wish yourself and everyone happy Spring Festival.