reactjszustand

Fetching multiple states with Zustand/React (shorthand syntax)


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()

Solution

  • Short Answer

    No, these methods are not identical.

    Long Answer

    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.

    Further suggestion

    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)