Remove actions from store for simpler API
See original GitHub issueI am realizing I should have shared this idea earlier… now v3 is released so it’s a bit late… or is it?
The premise of this idea is that it’s always felt a bit odd to keep the actions themselves inside the store. I guess a dev might want to change the actions dynamically but I’d venture to say this is not happening in 99% of use cases.
So… I was playing with an idea of how I might be able to use zustand in a more casual way. I wanted to be able to easily lift my state from a local useState
to a “global” zustand store. I tweeted about it here. Within that tweet there is a codesandbox with a playground exploring this idea.
The core idea of the playground is something like this:
// `globalState` uses zustand behind the scenes
const [useName, setName] = globalState('Tim') // Store a simple literal
const [usePet, setPet] = globalState({ type: 'Cat', name: 'Nacho') // Or store an object
const App = () => {
const name = useName()
const pet = usePet() // could use a selector here if you want
return (
<div>
// Call the setters from anywhere!
<button onClick={() => setName('Bob')}>Change Name</button>
<button onClick={() => setPet({ name: 'Beanie' })}>Change Pet Name</button>
</div>
)
}
So what did I learn from the idea?
That zustand stores are really about the data inside and subscribing to that data. The actions do not feel like they belong inside, they are just overhead. All that is really needed is exposing the set and get functions.
I realize this is all possible with v3 and you might be tempted to close this because of that reason, but I’m wondering if this mental shift should be more baked into the docs, or code, or both?
This is what I imagine it looking like (using the readme example). FWIW I love how v3 hangs additional methods on the hook, I also came to this conclusion recently.
import create from 'zustand'
const useCount = create(0) // Just provide the state, no actions
// Now, if you want create bespoke actions using the exposed useCount.set
// Side note: I think it should be called useCount.get() to get the state, just shorter and more elegant
const increase = () => useCount.set(state => ({ count: state.count + 1 })),
const reset = () => useCount.set({ count: 0 })
function Counter() {
const count = useCount()
return <h1>{count}</h1>
}
function Controls() {
return <button onClick={increase}>up</button>
}
As you can see this simplifies the API greatly! Thoughts??
Issue Analytics
- State:
- Created 3 years ago
- Comments:15 (8 by maintainers)
Top GitHub Comments
Thank you for all the consideration and suggestions on how I can use the v3 api. I think I am happy with the below as a compromise, which is possible with existing v3 api.
@zoontek Now that the
setState
(andgetState
) are available on the hook (and vanilla store) I will likely start to prefer to use those instead of addingactions
to my store structure. And I’ll likely just use the hook version, even though it’s a bit odd to access the prototype methods it is also convenient enough for me to prefer it.So instead of this
I’ll be trialing this approach instead 👍
Decided to use same approach, but also declare a namespace to organize it: