MobX依赖收集

2019-11-14  本文已影响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>
上一篇 下一篇

猜你喜欢

热点阅读