Zustand State Management Guide

react
zustand
state management

Installation

npm install zustand
# or
yarn add zustand

Creating a Store

import create from 'zustand'
 
const useStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))

Using the Store in Components

function BearCounter() {
  const bears = useStore((state) => state.bears)
  return <h1>{bears} around here...</h1>
}
 
function Controls() {
  const increasePopulation = useStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}

Async Actions

const useStore = create((set) => ({
  fishies: {},
  fetch: async (pond) => {
    const response = await fetch(pond)
    set({ fishies: await response.json() })
  },
}))

Nested Objects

const useStore = create((set) => ({
  lush: { forest: { contains: { a: "bear" } } },
  set: (fn) => set(produce(fn)),
}))
 
const set = useStore((state) => state.set)
set((state) => {
  state.lush.forest.contains = null
})

Computed Values

const useStore = create((set) => ({
  todos: [],
  addTodo: (text) => set((state) => ({ todos: [...state.todos, text] })),
  get completedTodos() {
    return this.todos.filter(todo => todo.completed)
  },
}))

Middleware

import { persist } from 'zustand/middleware'
 
const useStore = create(
  persist(
    (set, get) => ({
      fishes: 0,
      addAFish: () => set({ fishes: get().fishes + 1 }),
    }),
    {
      name: 'food-storage', // unique name
      getStorage: () => localStorage, // (optional) by default, 'localStorage' is used
    }
  )
)

Combining Multiple Stores

const useBearStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))
 
const useFishStore = create((set) => ({
  fishes: 0,
  addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
}))
 
const useStore = create((...a) => ({
  ...useBearStore(...a),
  ...useFishStore(...a),
}))

TypeScript Support

import create from 'zustand'
 
interface BearState {
  bears: number
  increase: (by: number) => void
}
 
const useBearStore = create<BearState>()((set) => ({
  bears: 0,
  increase: (by) => set((state) => ({ bears: state.bears + by })),
}))

Subscribing to State Changes

const unsub = useStore.subscribe(console.log)
useStore.setState({ paw: true })
// { paw: true }
unsub()

Remember, Zustand is designed to be simple and straightforward. It provides a minimal API that covers most state management needs while remaining flexible for more complex scenarios.