当前位置:网站首页>Deeply understand the working mechanism behind ngrx effect

Deeply understand the working mechanism behind ngrx effect

2021-06-23 22:25:37 JerryWang_ Wang Zixi

Blog address :https://indepth.dev/posts/120...

an action is a constituent of a reducer, as well as of an effect. NgRx ensures that actions are first handled by the reducers, after which they will eventually be intercepted by the effects.

actions yes reducer Component part , It's also effect Component part . NgRx Make sure that the operation is carried out by reducer Handle , And then they'll eventually be effect Intercept .

Reducer Handle action, Then be effect analysis .

Providing the effects

forRoot and forFeature The input parameters received are other .ts file export Of class, Not specific class example . according to class get metadata.

EffectsModule.forRoot Can only be called once , Because this method instantiates other Ngrx Important services , such as EffectsRunner and EffectSources.

Spartacus The example in , Not used forRoot Method .

effects The input parameter is an array :

These are all concrete effect Realization class:

Once the effects (classes) are registered, in order to set them up, an observable will be created (with the help of EffectSources) and subscribed to (thanks to EffectRunner);
  • reducer: the shape of application
  • state entity: where the app information is kept, also where the place actions meet reducers, meaning it's where reducers being invoked, which may cause state changes

State Equivalent to the model layer , and Store It's just consumers and State Middleware between .

state It's where applications store data .

  • the Store entity - the middleman between the data consumer(e.g: a smart component) and the model(the State entity)

Store It's the data consumer , such as Angular Component and model( Namely state entity) Between the middle layers .

effects Will be merge.

all the effects(e.g: those created by createEffect for example) will be merged into one single observable whose emitted values will be actions.

Effects Will be merge Become a Observable, the latter emit Of value Namely actions.

Store It's also stream Of Observer:

effect ---->actions
                |-  By  store intercept

actions$

AC It means a type :extends ActionCreator<string, Creator>

V = Action,V If you don't specify , The default type is Action:

  • ScannedActionsSubject: comes from @ngrx/store and it is a Subject(thus, an Observable) that emits whenever actions are dispatched, but only after the state changes have been handled.
So, when an action is dispatched(Store.dispatch()), the State entity will first update the application state depending on that action and the current state with the help of the reducers, then it will push that action into an actions stream, created by ScannedActionsSubject.

Store dispatch after , First, state machine migration , Applications state change , The series passed reducer drive . And then put action push To action stream Go to .

By setting the Actions' source to ScannedActionsSubject, every time we have something like this.actions$.pipe().subscribe(observer) the observer will be part of ScannedActionsSubject's observers list, meaning that when the subject emits an action(e.g: subject.next(action)), all the registered observers will receive it. This should explain why all the effects will receive the same actions, but, with ofType's help, these can be filtered out - OfType The filtering effect of .

OfType

In order to determine which actions should trigger which effects, the OfType custom operator is used.

maintain action and effect The mapping relation of .

OfType It's also used inside RxJS Of filter Operator:

have a look Observable.pipe The implementation of the :

export class Observable<T> implements Subscribable<T> {
  /* ... */
  
  pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
  
  /* ... */
}
where OperatorFunction<T,A> specifies the type of a function that receives an observable as a parameter and returns another observable:

OperatorFunction: Receives two type parameters ,T Represents the original Observable Type of package ,A Represents the new... Returned Observable Types included .

Finally return to a new Observable, The type is B.

Store.dispatch(event)

It signals that an event that requires state changes is sent from the UI(e.g a smart component).

Store.dispatch() will push the action(event) into an actions stream(which is different from the one that belongs to the effects):

Action

It can be understood as an instruction , adopt UI / Service / Effects Come on dispatch.

Creator<P, R> is simply a function takes up a parameter of type P and returns an object of type R.

reducer

Reducers are pure functions that are responsible for state changes.

reducer Of interface Definition :

export interface ActionReducer<T, V extends Action = Action> {
  (state: T | undefined, action: V): T;
}

The above grammar defines a interface, The interface Describes a function type , Inside the braces is the specific definition of the function type , Parentheses define the input interface for this function , This function takes two input parameters , The formal parameter is state and action, The types are T( acceptable undefined) and V, The colon after the parentheses , The return parameter type defined should also be T.

Obviously , This function is a state machine , Based on the current state and input action( It can be understood as an instruction , Instructions that trigger state transitions ), Return to new status .

TypeScript Functions are described by defining interfaces signature In this way , Has been and ABAP Inside interface It's very different .

With address-verification.reducer.ts Inside reducer For example : The reducer How to be setup?

stay index.ts in , adopt import * as To distinguish those with the same name reducer:

adopt getReducers United return :

adopt reducerToken and getReducers Provide provider Information :

Provider stay @NgModule In the metadata provided :

Store

It doesn't store data , It's just a middleware .

Source code :

export class Store<T> extends Observable<T> implements Observer<Action> {
  constructor(
    state$: StateObservable,
    private actionsObserver: ActionsSubject,
    private reducerManager: ReducerManager
  ) {
    super();

    this.source = state$;
  }
  
  /* ... */
}

Store Receiving data from the outside world , namely state$.

Every time the source (state$) emits, the Store class will send the value to its subscribers.
allows consumer ️ state communication
        ️
        |
        |
-----------      newState          -----------                         
|         | <-------------------   |         |                         
|         |  Store.source=$state   |         |
|         |                        |         | <---- storing data 
|  Store  |      Action            |  State  |                         
|         | -------------------->  |         |
|         |   Store.dispatch()     |         |          
-----------                        ----------- 
                                   |        ️
                          Action   |        | newState
                                   |        |
                                   ️        |
                                  ------------- 
                                  |           | 
                                  |  Reducer  | <---- state changes
                                  |           | 
                                  -------------

more Jerry The original article of , All in :" Wang Zixi ":

版权声明
本文为[JerryWang_ Wang Zixi]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/06/20210623222519693V.html