Dear reader,
In the last few years, I've been using my own global store implementation with great success (yes, I'm aware there exist a bazillion "redux like" stores). My one's called tiny-atom.
In particular, the following 4 requirements for a global store emerged from my needs:
For example, tiny-atom uses requestAnimationFrame
to delay/batch the re-renders.
If naively implemented – a child component re-renders once from parent re-render, once from it's own subscription.
For example, a child component can break reading something non existant from store, when parent was supposed to un-render that child.
Important for performance, when many components bind to small slices of the shared state.
My current implementation is not Concurrent Mode ready. So, excitedly, I've tried out the new useMutableSource
in [email protected]
in place
of my current approach. It works pretty great! The useMutableSource
hook takes care of requirements 1-3 out of the box only leaving requirement 4 to the implementer!
Right now, I'm looking for the following answers:
How to correctly prevent re-rendering after store change if new snapshot is shallowly equal?
You can see my current approach below, but I don't think it's correct wrt Concurrent Mode.
UPDATE: I have updated the gist and code sandbox with a correct (?) implementation of selective subscription now. No more mutating refs.
Is this type of implementation fully Concurrent Mode compatible?
I tried running this simple store implementation through the https://github.com/dai-shi/will-this-react-global-state-work-in-concurrent-mode test suite and the following checks fail:
✕ check 7: proper branching with transition
✕ check 9: no tearing with auto increment
My concern is - does that mean useMutableSource
still has some tearing issues in some cases? (Note: I haven't looked into the the implementation of the test suite closely).
UPDATE Anyone know how to convert this super simple store into a fully React compliant store? E.g. I don't mind if it's turned into a useState/useReducer as long as it can be used in a similar manner?
I've put the code used in my exercise here: https://codesandbox.io/s/flamboyant-keller-m9unj
App.js
- a demo app for exploring the 4 requirements abovecreateStoreModern.js
- simpler store used inuseMutableSource
implementaionuseStoreModern.js
- implementation of store hooks usinguseMutableSource
createStoreLegacy.js
- more complex store that allows order specified subscriptionsuseStoreLegacy.js
- implementation of hooks withoutuseMutableSource
I'm also including the code for the modern implementation directly below
There's another long thread: reduxjs/react-redux#1351
reduxjs/react-redux#1351 (comment)
Check out the official docs about branching and rebasing. Links in this tweet: https://twitter.com/dai_shi/status/1236865863476580352
In short, you would see state changes in
startTransition
, while we want to show the stale state in the transition.They use useState/useReducer underneath, which is the only way I know to support "state branching."
(Sorry for short responses. Can expand more if you need.)