Created
October 10, 2022 03:36
-
-
Save luo3house/7a01203f54ff45cadf96c443fc9fadbe to your computer and use it in GitHub Desktop.
mobx-react-lite: useObserver completely follow component effects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { getDependencyTree, Reaction } from "mobx" | |
import React, { useRef, useState, useLayoutEffect } from "react" | |
import { isUsingStaticRendering } from "./staticRendering" | |
import { printDebugValue } from "./utils/printDebugValue" | |
function observerComponentNameFor(baseComponentName: string) { | |
return `observer${baseComponentName}` | |
} | |
function useMyObserverWithReaction<T>(fn: () => T, baseComponentName: string = "observed"): any { | |
if (isUsingStaticRendering()) { | |
return fn() | |
} | |
const reactionRef = useRef<Reaction | null>(null) | |
const [_, setState] = useState([]) | |
const forceUpdate = () => setState([]) | |
useLayoutEffect(() => { | |
const reaction = new Reaction(observerComponentNameFor(baseComponentName), () => { | |
forceUpdate() | |
}) | |
reactionRef.current = reaction | |
forceUpdate() | |
return () => { | |
reaction.dispose() | |
reactionRef.current = null | |
} | |
}, [0]) | |
const reaction = reactionRef.current | |
React.useDebugValue<Reaction | null>( | |
reaction, | |
reaction => reaction && printDebugValue(reaction) | |
) | |
let rendering: any = null | |
if (reaction) { | |
reaction.track(() => (rendering = fn())) | |
} else { | |
rendering = fn() // keep hooks | |
} | |
return rendering | |
} | |
export { useMyObserverWithReaction as useObserver } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment