Discussion: Multiple stores in one component
See original GitHub issueWhen using multiple stores in a component, it seems I have to change the style of which I consume a store. Store conventions can cause some headaches when using multiple stores in a component—conventions like: always having an actions
key, or multiple stores may have a loaded
key.
This shows the problem:
const Component = () => {
// This is my preferred way of using zustand
const { users, loaded, actions } = useUsersStore()
// But now this code will break because of duplicate variable declarations
const { comments, loaded, actions } = useCommentsStore()
}
So my only idea is to do this:
const Component = () => {
const usersStore = useUsersStore()
const commentsStore = useCommentsStore()
// Then work with it as a domain object, which is kind of nice actually.
if (usersStore.loaded) { ... }
return <div>{ commentsStore.comments }</div>
}
However, things get a bit more complicate if I want to use selectors. Atomic selectors are promoted in the docs because they are showing simple use-cases, but those might be cumbersome here because I’d have to “namespace” each clashing variable, like so:
const Component = () => {
const usersActions = useUsersStore(state => state.actions)
const usersLoaded = useUsersStore(state => state.loaded)
const comments = useCommentsStore(state => state.comments)
const commentsActions = useCommentsStore(state => state.actions)
const commentsLoaded = useCommentsStore(state => state.loaded)
// Then work with it as a domain object, which is kind of nice actually.
if (usersLoaded) { ... }
return <div>{ comments }</div>
}
Maybe that’s not so bad. Thoughts?
I’d prefer the domain objects though with a nice selection API, maybe something that uses lodash pick
and get
under the hood.
const Component = () => {
const usersStore = useUsersStore(['users', 'loaded', 'actions'])
const commentsStore = useCommentsStore(['comments', 'loaded', 'actions'])
// Then I just use the domain objects as shown before
}
The string shorthand would even be a very nice API for atomic selections…
const Component = () => {
const usersActions = useUsersStore('actions')
const usersLoaded = useUsersStore('loaded')
const comments = useCommentsStore('comments')
const commentsActions = useCommentsStore('actions')
const commentsLoaded = useCommentsStore('loaded')
}
It could support lodash get
style deep selections too…
const Component = () => {
const loadAllUsers = useUsersStore('actions.loadAll')
}
If the core lib didn’t support this, would this be possible to add via a middleware?
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
@timkindberg Um, why don’t you simply rename your destructured variables ?
Just to add a thought to this issue, destructuring state like in the first post :
or in the post just above mine make the use of zustand loose its interest, as the component will rerender when any state of the store is upload, since it’s subscribed to the all store, and not to a slice of it. That the React’s context behavior. Renaming the variables during the destructuring step is the natural solution, IMO.