看了一点点源码,看不懂。。。
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)
}
- useObserver 使用这种方式强行触发渲染
export function useForceUpdate() {
const [, setTick] = useState(0)
const update = useCallback(() => {
setTick(tick => tick + 1)
}, [])
return update
}
- computed和observable实现了observable接口
- 在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上
- 属性装饰器先于类装饰器执行,也是就observerable先于observe声明,收集依赖的时候被观察者已经全部声明好了
- 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
}
- observable类型的Proxy get 的时候会执行reportObserved, reportObserved方法会把observable放到__mobxGlobals.trackingDerivation全局Reaction对象的 newObserving数组里
- 执行track方法的时候会把Reaction上的newObserving赋值给observing,执行addObserver和removeObserver;把Reaction放到IObservable的 observers: Set<IDerivation>
网友评论