feat: React 18 support
It appears that react-solid-state doesn't support the new Renderer in React 18.
Using the old render function with React 18 still works, but switching to the new render function in React 18 doesn't work.
Yeah I suspected this would happen. I just haven't been up on the new primitives. React 18 basically requires a new implementation for effectful state libraries.
Here's a rough POC fix
I suspect React 18 currently isn't working because setState() calls are now being batched. In my simple proof-of-concept fix, I'm using the new useSyncExternalStore hook to force updates instead of a call to setState().
function useNewForceUpdate() {
const [tick, setTick] = rState(0);
const fn = rCallback(() => {
setTick((t) => t + 1);
return () => {};
}, []);
const fn2 = rCallback(() => tick, []);
const state = rSyncExternalStore(fn, fn2);
return fn;
}
I expect that this can be cleaned up, but I was mostly concerned with figuring out what was going on.
Awesome. Thanks for looking into this. I guess MobX would have a similar mechanism. If this works tempted to do this. I suppose couldn't hurt to see where they landed, now that we know what to look for.
I took a look at MobX's current React 18 support. While MobX currently works with React 18, it doesn't yet play nicely with suspense/concurrent features (see comments on the PR introducing React 18 support). The author of that PR calls out using useSyncExternalStore as their most likely path forward to greater React 18 support, but it sounds like they'll need to do a larger refactor to make that work and they want to wait and get more info about real world usage first. Discussion is ongoing here.
I'll note that it appears that MobX already worked with React 18's change detection, as the PR which "adds" support for React 18 only updates the package.json to list React 18 support and updates a bunch of internal tests. None of the distributed MobX package code needed to be updated though (well ok, there was one small typescript typing change, but it didn't affect the javascript). So currently MobX doesn't use useSyncExternalStore or any of the new React 18 hooks (which has allowed them to add React 18 support in a backwards-compatible minor release).
All of this is to say that, at the moment, it doesn't look like MobX can provide much insight but we should keep an eye on this issue.
Just remove StrictMode and it will play nicely with React 18
Just remove StrictMode and it will play nicely with React 18
Does this change sliminate the need to use useSyncExternalStore?