preface

let target = observable(obj)
Copy the code

Atom is used in Mobx to monitor data being observed and modified. When setting the target property descriptor, an Instance of ObservableValue, a subclass of Atom, is created for each key.

ObservableValue

If the return value of obserable(obj) is “bright” and obj is “dark “, then the ObservableValue instance is a one-way bridge from” bright “to” dark “. The getters and setters for target’s corresponding key call the corresponding methods of this instance.

  • value_

This property holds the obj object’s corresponding key descriptor. Value

  • The get:

This method is called when a target property is accessed. It returns the corresponding valuereportObserved for the key of the original OBj object,

 public get(): T {
    this.reportObserved()
    return this.dehanceValue(this.value_)
}
Copy the code

A call to GET indicates that the key is dependent, and reportObserved is called to handle the dependency.

  • reportObserved

This method inherits from Atom, and the most valuable thing in this function is determining dependencies.

export function reportObserved(observable: IObservable): boolean { ... const derivation = globalState.trackingDerivation if (derivation ! == null) { if (derivation.runId_ ! == observable.lastAccessedBy_) { observable.lastAccessedBy_ = derivation.runId_ derivation.newObserving_! [derivation.unboundDepsCount_++] = observable if (! observable.isBeingObserved_ && globalState.trackingContext) { observable.isBeingObserved_ = true observable.onBO() } } return true } else if (observable.observers_.size === 0 && globalState.inBatch > 0) { queueForUnobservation(observable) } return false }Copy the code

GlobalState trackingDerivation is a IDerivation types of data, or “derived”, it has a famous implementation class, called Reaction. Easy to understand: Derivation is the observer of Observable data. When this code runs will create a reaction, and hung globalState. TrackingDerivation, process in the analytical autorun source to specific analysis.

auturun(()=>{... })Copy the code

In summary, here we adopt the derivation. NewObserving_! [derivation. UnboundDepsCount_ + +] = observables, determine the derivation of the ObservableValue instance has a dependency.

  • The set and setNewValue

Set or setNewValue is called when setting/modifying a value for target, and setNewValue is called inside the set.

public set(newValue: T) { const oldValue = this.value_ newValue = this.prepareNewValue_(newValue) as any ... if (newValue ! == globalState.UNCHANGED) { this.setNewValue_(newValue) } } setNewValue_(newValue: T) { const oldValue = this.value_ this.value_ = newValue this.reportChanged() ... }Copy the code

SetNewValue is triggered to indicate a value change, and the dependency needs to be notified to handle the change accordingly. In this case, reportChanged is called.

  • reportChanged

This method also inherits from Atom

 public reportChanged() {
        startBatch()
        propagateChanged(this)
        endBatch()
    }
Copy the code

PropagateChanged finds all derivation that has dependencies on it from ObservableValue instance Observable and calls onBecomeStale_, which is defined in Reaction. After a series of complex calls, Can make dependent functions run again.

export function propagateChanged(observable: IObservable) { // invariantLOS(observable, "changed start"); if (observable.lowestObserverState_ === IDerivationState_.STALE_) return observable.lowestObserverState_ = IDerivationState_.STALE_ // Ideally we use for.. of here, but the downcompiled version is really slow... observable.observers_.forEach(d => { if (d.dependenciesState_ === IDerivationState_.UP_TO_DATE_) { if (__DEV__ && d.isTracing_ ! == TraceMode.NONE) { logTraceInfo(d, observable) } d.onBecomeStale_() } d.dependenciesState_ = IDerivationState_.STALE_ }) // invariantLOS(observable, "changed end"); }Copy the code

To be continued

Mobx “observation” here is the end of the basic part of the code, but its legacy two problems: globalState. When was trackingDerivation determine and observables. Observers_ is how to collect.

The next section begins parsing the source code for the Mobx “reaction” section to answer these two questions