Skip to main content

Zustand

Tips

Only export custom hooks

// Store itself is not exported
const useBearStore = create((set) => ({
bears: 0,
fish: 0,
increasePopulation: (by) =>
set((state) => ({ bears: state.bears + by })),
eatFish: () => set((state) => ({ fish: state.fish - 1 })),
removeAllBears: () => set({ bears: 0 }),
}))

// consumers simply import this custom hook instead of writing selectors
export const useBears = () => useBearStore((state) => state.bears)

// useBearStore not exported so invalid, avoids consumers accidentally subscribing to whole store
const { bears } = useBearStore()

Separate Actions from State

const useBearStore = create((set) => ({
bears: 0,
fish: 0,
// ⬇️ separate "namespace" for actions
actions: {
increasePopulation: (by) =>
set((state) => ({ bears: state.bears + by })),
eatFish: () => set((state) => ({ fish: state.fish - 1 })),
removeAllBears: () => set({ bears: 0 }),
},
}))

export const useBears = () => useBearStore((state) => state.bears)
export const useFish = () => useBearStore((state) => state.fish)

// 🎉 one selector for all our actions
export const useBearActions = () =>
useBearStore((state) => state.actions)

Deep Dive

References