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 }),
}))