react-solid-state icon indicating copy to clipboard operation
react-solid-state copied to clipboard

feat: React 18 support

Open jorroll opened this issue 3 years ago • 6 comments

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.

jorroll avatar Jun 10 '22 01:06 jorroll

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.

ryansolid avatar Jun 10 '22 03:06 ryansolid

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.

jorroll avatar Jun 23 '22 01:06 jorroll

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.

ryansolid avatar Jun 23 '22 02:06 ryansolid

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.

jorroll avatar Jun 29 '22 19:06 jorroll

Just remove StrictMode and it will play nicely with React 18

cr4zyc4t avatar Mar 02 '23 09:03 cr4zyc4t

Just remove StrictMode and it will play nicely with React 18

Does this change sliminate the need to use useSyncExternalStore?

thednp avatar May 25 '24 06:05 thednp