React 18 broke useAtomSelector in strict mode. This is because of lots of quirks with useSyncExternalStore that I coded circles around in React 17.
Stop fighting with useSyncExternalStore. It still has many quirks, doesn't solve any of the problems we wanted it to solve, and most importantly looks to be poorly supported by the React team - for example, transitions will likely never be supported.
Remove useSyncExternalStore usages. Instead,
add graph edges during render in useAtomInstance, handling strict mode double-renders and double-effect-invocations specifically. The impure operations are completely idempotent since generated ids are consistent for a given component thanks to useId
add a simple useEffect in EcosystemProvider
run selectors statically during render in useAtomSelector and then cache and destroy them in a very simple useEffect call
These changes make use of the new useId hook, which I believe was released in React 18, so we'd need a shim (or manual handling) to support React 17 again, though I don't think that's a very high priority - most people should be off React 17 by now.
@affects atoms, react
Issues
Resolves #83 - useAtomSelector is completely rewritten, cleaner, and should have no problems in strict mode in React 18
Closes #73 - this PR incorporates those changes, using the forbidden React internals only for improving Dev X and falling back to generating names if React does change their internals.
Description
React 18 broke
useAtomSelector
in strict mode. This is because of lots of quirks withuseSyncExternalStore
that I coded circles around in React 17.Stop fighting with
useSyncExternalStore
. It still has many quirks, doesn't solve any of the problems we wanted it to solve, and most importantly looks to be poorly supported by the React team - for example, transitions will likely never be supported.Remove
useSyncExternalStore
usages. Instead,useAtomInstance
, handling strict mode double-renders and double-effect-invocations specifically. The impure operations are completely idempotent since generated ids are consistent for a given component thanks touseId
useEffect
inEcosystemProvider
useAtomSelector
and then cache and destroy them in a very simpleuseEffect
callThese changes make use of the new
useId
hook, which I believe was released in React 18, so we'd need a shim (or manual handling) to support React 17 again, though I don't think that's a very high priority - most people should be off React 17 by now.@affects atoms, react
Issues
Resolves #83 -
useAtomSelector
is completely rewritten, cleaner, and should have no problems in strict mode in React 18Closes #73 - this PR incorporates those changes, using the forbidden React internals only for improving Dev X and falling back to generating names if React does change their internals.