-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Proposal: useStoreProxy hook #263
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 32efa68:
|
I like it and I would probably use it.
I would also be interested if this would be implemented. I wouldn't mind it bringing Zustand closer to Valtio, because why not using good features of other packages? |
Wrapping an entire tree of objects in proxies does not come for free or without problems, and I'm glad Zustand doesn't do it (and it's also the reason why I still prefer it over Valtio in my project, since I'm putting references to complex objects into my stores and 1. don't need them to be proxied, and 2. the proxying of them causes issues.) Stores that work with explicit mutations and selectors are a different approach to stores that are transparently mutable and subscribable through proxy magic, and Zustand and Valtio respectively each serve these approaches fine. The intention of the proposal above is not to turn Zustand into a proxy-based solution, but rather just provide a more convenient way to perform the most basic way to access the store. |
Exploring this further, I sort of accidentally ended up building my own state management library, which I am both proud and not proud of. :)~ If you want to take a look, here's Statery, but please consider it mostly experimental at this stage -- there's probably a whole bunch of use cases where it'll break that I haven't encountered yet. (I am using it in a real project, though, where it has been working just fine for what I'm doing with it.) With this, I'm closing this PR for the time being. Thanks for the feedback (also on Discord), everybody! |
This proposal was actually helpful to me personally. Here's the codesandbox with minimal example: https://codesandbox.io/s/react-typescript-forked-myfki?file=/src/App.tsx Note: react-tracked and valtio use same internal library under the hood. So, the behavior and performance should be basically equivalent. |
Summary
This is a proposal for a new hook named
useStoreProxy
. This hook wraps around a store created with zustand'screate
function and provides what I feel is more convenient access to the store data while maintaining reactive properties. It's inspired by both valtio and me getting tired of writing selector functions:Or:
Both of these will only rerender if any property of the snapshot is accessed, and only if that specific property is changed: essentially,
useStoryProxy(store).foo
is 100% equivalent tostore(s => s.foo)
.Accessing multiple values reactively becomes very straight-forward:
The implementation makes use of a Proxy object, so the usual caveats apply. It should be noted that I've added code to the Proxy that specifically forbids setting instead of reading state.
Example Sandbox:
https://codesandbox.io/s/broken-https-bgq29?file=/src/App.tsx
Caveats:
ClickyGame
example above,snapshot.api.increaseCounter
will make the component re-render every timesnapshot.api
changes, notsnapshot.api.increaseCounter
. Theoretically, there could be some magic here to wrap nested objects in similar proxies, but this would possible be non-trivial, and may move Zustand too close to Valtio.Checklist:
useStoreProxy
?)Complementary Kitten Picture: