Are both ways of fetching states from the Zustand store identical in respect of re-renders on state changes?
Method described in the documentation:
const nuts = useStore(state => state.nuts)
const honey = useStore(state => state.honey)
Shorthand:
const { nuts, honey } = useStore()
No, these methods are not identical.
As mentioned in the zustand readme:
Fetching everything
You can, but bear in mind that it will cause the component to update on every state change!
const state = useStore()
So, When you select certain slices of state using a selector, the component will only update/rerender when the selected values change.
When you call useStore()
without passing any parameters to it, you are effectively subscribing your component to the whole state. As a metaphor, you could say that "zustand will be asking the component to update/rerender on any state change, anywhere in the state tree". Object destructuring in the shorthand syntax is just syntactic sugar to assign variables to object properties in a quicker way. The value that useStore()
returns (and subscribes the component to) is still the whole state.
So, if you use const { nuts, honey } = useStore()
, you may run into performance issues. Whether those issues will be noticeable or not depends on the app, but I'd say it's easy enough to just use selectors and not have to worry about it.
If you need to select all the slices of state in a single useStore(...)
call, the recommended method is to use suitable selectors for that.
Quoting from Selecting multiple state slices
import shallow from 'zustand/shallow'
// Object pick, re-renders the component when either state.nuts or state.honey change
const { nuts, honey } = useStore(state => ({ nuts: state.nuts, honey: state.honey }), shallow)
// Array pick, re-renders the component when either state.nuts or state.honey change
const [nuts, honey] = useStore(state => [state.nuts, state.honey], shallow)
// Mapped picks, re-renders the component when state.treats changes in order, count or keys
const treats = useStore(state => Object.keys(state.treats), shallow)