iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Zustand

Zustand: a tiny, hook-based state library for React. The default choice for client state in 2026.

React — Zustand

EXAMPLE
// Install: npm install zustand
import { create } from 'zustand';

// ===== Define a store =====
const useCounter = create((set, get) => ({
  count: 0,
  inc: () => set((s) => ({ count: s.count + 1 })),
  reset: () => set({ count: 0 }),
  doubleIt: () => set((s) => ({ count: get().count * 2 })),
}));

// ===== Use it =====
function Counter() {
  const count = useCounter((s) => s.count);
  const inc = useCounter((s) => s.inc);
  return <button onClick={inc}>{count}</button>;
}

// Selectors prevent re-renders when unrelated state changes.

// ===== TypeScript =====
interface CartStore {
  items: Item[];
  add: (item: Item) => void;
  remove: (id: number) => void;
}

const useCart = create<CartStore>()((set) => ({
  items: [],
  add: (item) => set((s) => ({ items: [...s.items, item] })),
  remove: (id) => set((s) => ({ items: s.items.filter(i => i.id !== id) })),
}));

// ===== Middleware =====
import { devtools, persist } from 'zustand/middleware';

const useStore = create(
  devtools(
    persist(
      (set) => ({ theme: 'light', setTheme: (t) => set({ theme: t }) }),
      { name: 'app-storage' }
    )
  )
);

// ===== Patterns =====
// - Slice pattern: split big stores into composable slices
// - Selectors with shallow compare for object selectors
// - Subscribe outside React with useStore.subscribe()
// - Default export for global single-instance stores

// ===== Pitfalls =====
// - Selecting whole state -> re-renders on every change
// - Using Zustand for server state (use TanStack Query)
// - Mutating state directly (use set() always)

Why it matters

Zustand: tiny, fast, hook-based store with middleware (persist, devtools, immer). Slice with selectors, persist with localStorage, debug with devtools. The default choice for cross-tree client state in 2026.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import { create } from 'zustand';
const useStore = create((set) => ({
    count: 0,
    inc: () => set((s) => ({ count: s.count + 1 })),
}));
Try it Yourself »

Discussion

Loading…