Learning
Zustand

Gyakorlati példák

Counter, theme switcher persisttel, async auth store, és globális UI state (modal + sidebar).

Példa 1 – Counter

import { create } from "zustand"

interface CounterState {
  count: number
  step: number
  increment: () => void
  decrement: () => void
  reset: () => void
  setStep: (step: number) => void
}

export const useCounterStore = create<CounterState>((set) => ({
  count: 0,
  step: 1,
  increment: () => set((state) => ({ count: state.count + state.step })),
  decrement: () => set((state) => ({ count: state.count - state.step })),
  reset: () => set({ count: 0 }),
  setStep: (step) => set({ step }),
}))

Példa 2 – Theme switcher (persist)

import { create } from "zustand"
import { persist } from "zustand/middleware"

type Theme = "light" | "dark" | "system"

interface ThemeState {
  theme: Theme
  setTheme: (theme: Theme) => void
  toggleTheme: () => void
}

export const useThemeStore = create<ThemeState>()(
  persist(
    (set) => ({
      theme: "system",
      setTheme: (theme) => set({ theme }),
      toggleTheme: () =>
        set((state) => ({ theme: state.theme === "light" ? "dark" : "light" })),
    }),
    { name: "theme" }
  )
)

Példa 3 – Auth (async)

import { create } from "zustand"

interface User {
  id: string
  name: string
  email: string
  role: "admin" | "user"
}

interface AuthState {
  user: User | null
  isLoading: boolean
  error: string | null
  login: (email: string, password: string) => Promise<void>
  logout: () => void
}

export const useAuthStore = create<AuthState>((set) => ({
  user: null,
  isLoading: false,
  error: null,
  login: async (email, password) => {
    set({ isLoading: true, error: null })
    try {
      const user = await fakeLoginApi(email, password)
      set({ user, isLoading: false })
    } catch {
      set({ error: "Hibás email vagy jelszó", isLoading: false })
    }
  },
  logout: () => set({ user: null, error: null }),
}))

Példa 4 – Globális UI state

import { create } from "zustand"

interface UIState {
  isSidebarOpen: boolean
  activeModal: string | null
  toggleSidebar: () => void
  openModal: (modalId: string) => void
  closeModal: () => void
}

export const useUIStore = create<UIState>((set) => ({
  isSidebarOpen: false,
  activeModal: null,
  toggleSidebar: () => set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
  openModal: (modalId) => set({ activeModal: modalId }),
  closeModal: () => set({ activeModal: null }),
}))

On this page