美文网首页
MobX依赖收集

MobX依赖收集

作者: 粑粑八成 | 来源:发表于2019-11-14 17:36 被阅读0次

    看了一点点源码,看不懂。。。
    1.mobx-react observe 在装饰类组价,把component的render函数作为render props传给了Observe组件,Observe组件使用mobx-react-lite的useObserver包装render函数

    // Unwrap forward refs into `<Observer>` component
        // we need to unwrap the render, because it is the inner render that needs to be tracked,
        // not the ForwardRef HoC
        if (ReactForwardRefSymbol && componentClass["$$typeof"] === ReactForwardRefSymbol) {
            const baseRender = componentClass.render
            if (typeof baseRender !== "function")
                throw new Error("render property of ForwardRef was not a function")
            return forwardRef(function ObserverForwardRef() {
                return <Observer>{() => baseRender.apply(undefined, arguments)}</Observer>
            })
        }
    
        // Function component
        if (
            typeof componentClass === "function" &&
            (!componentClass.prototype || !componentClass.prototype.render) &&
            !componentClass.isReactClass &&
            !Object.prototype.isPrototypeOf.call(Component, componentClass)
        ) {
            return observerLite(componentClass)
        }
    
    1. useObserver 使用这种方式强行触发渲染
    export function useForceUpdate() {
        const [, setTick] = useState(0)
    
        const update = useCallback(() => {
            setTick(tick => tick + 1)
        }, [])
    
        return update
    }
    
    1. computed和observable实现了observable接口
    2. 在useObserver中,会声明一个Reaction对象,Reaction是mobx包的类,执行Reaction的track方法收集依赖
      传入reaction的第二个参数应该是触发渲染的时候调用的
    reaction.current = new Reaction(`observer(${baseComponentName})`, () => {
                forceUpdate()
     })
    
    reaction.current.track(() => {
            try {
                rendering = fn()
            } catch (e) {
                exception = e
            }
      })
    

    会把Reaction对象放到__mobxGlobals.trackingDerivation上

    1. 属性装饰器先于类装饰器执行,也是就observerable先于observe声明,收集依赖的时候被观察者已经全部声明好了
    2. trace方法会调用trackDerivedFunction进行依赖的收集,把globalState.trackingDerivation赋值给当前reaction,然后执行fn进行收集依赖,完成之后把globalState.trackingDerivation还原
    export function trackDerivedFunction<T>(derivation: IDerivation, f: () => T, context: any) {
        const prevAllowStateReads = allowStateReadsStart(true)
        // pre allocate array allocation + room for variation in deps
        // array will be trimmed by bindDependencies
        changeDependenciesStateTo0(derivation)
        derivation.newObserving = new Array(derivation.observing.length + 100)
        derivation.unboundDepsCount = 0
        derivation.runId = ++globalState.runId
        const prevTracking = globalState.trackingDerivation
        globalState.trackingDerivation = derivation
        let result
        if (globalState.disableErrorBoundaries === true) {
            result = f.call(context)
        } else {
            try {
                result = f.call(context)
            } catch (e) {
                result = new CaughtException(e)
            }
        }
        globalState.trackingDerivation = prevTracking
        bindDependencies(derivation)
    
        warnAboutDerivationWithoutDependencies(derivation)
    
        allowStateReadsEnd(prevAllowStateReads)
    
        return result
    }
    
    1. observable类型的Proxy get 的时候会执行reportObserved, reportObserved方法会把observable放到__mobxGlobals.trackingDerivation全局Reaction对象的 newObserving数组里
    2. 执行track方法的时候会把Reaction上的newObserving赋值给observing,执行addObserver和removeObserver;把Reaction放到IObservable的 observers: Set<IDerivation>

    相关文章

      网友评论

          本文标题:MobX依赖收集

          本文链接:https://www.haomeiwen.com/subject/bizrictx.html