-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incompatible with React Forget compiler #3874
Comments
At the moment React Forget assumes that all object reads are from immutable objects. E.g. something like So we're depending on some future option to opt-out form this at object or component level. Until then the architectures are fundamentally incompatible, as far as I can see atm (without severely regressing the DX of MobX). On the upside, many of the optimisations that are offered now by Forget, were already provided by MobX. |
I've been playing with the compiler playground and the only issues I could find are with a store accessed either from a global directly or through a global getter function (it seems to cache those), but if they come either via props or via a hook (including context) it seems ok, so maybe the solution is to just replace globals with a silly hook? For example, if we have something like like: the user could turn that into const useRootStore = () => getRootStore() and I think he should be ok Expand the source map section in the right, it is easier to follow that way. |
This looks indeed very promising! @xaviergonz As a user of the library: Specifically, it is still very easy to create accidental render cascades with functions (if you don't use useCallback). In addition, I'd classify mobx's strength at avoiding unnecessary render calls with memoization. Forget is different - it can only run parts of a function, and it can then avoid render cascades to not-impacted parts. So, overall, we suspect that react-forget would create additional performance improvements for us. That said, I can't measure the impact for various reasons (mainly time constraints). |
Hey folks, if you're using MobX-State-Tree, I have some early progress on React Compiler compatibility. A custom hook like this will work for properties (I haven't expanded it to views yet, but it should be possible) using MST snapshots: import { useEffect, useState } from "react";
import { IStateTreeNode, getSnapshot, onSnapshot } from "mobx-state-tree";
export function useObservableProperty<
T extends IStateTreeNode,
K extends keyof ReturnType<typeof getSnapshot<T>>
>(model: T, property: K) {
const [value, setValue] = useState(() => {
const snapshot = getSnapshot(model);
return snapshot[property];
});
useEffect(() => {
if (!model) return;
const disposer = onSnapshot(model, (snapshot) => {
if (snapshot[property] !== value) {
setValue(snapshot[property]);
}
});
return disposer;
}, [model, property, value]);
return value;
}
export function useObservable<T extends IStateTreeNode>(model: T) {
return new Proxy({} as ReturnType<typeof getSnapshot<T>>, {
get: (target, property) => {
if (typeof property === "string") {
return useObservableProperty(
model,
property as keyof ReturnType<typeof getSnapshot<T>>
);
}
return undefined;
},
});
} I know there have been some issues with hooks and MobX before, but I think we need to figure out some path forward to be React Compiler ready. I looked at using I hope folks find this helpful. I'm reaching out to MST contributors for feedback, and I'll be experimenting some more over the coming weeks. Happy to adjust my approach if there's a more MobX-focused path forward. I'd be happy to compare notes! |
Intended outcome: success
Actual outcome: Found the following incompatible libraries: mobx
How to reproduce the issue:
Versions
6.12.3
The text was updated successfully, but these errors were encountered: