适用人群:React 开发者
难度:低
预计学习时间:3-5小时
什么是 Zustand?
Zustand 是 React 生态中最轻量的状态管理库,API 极简,无样板代码,无需 Provider,比 Redux 简单 10 倍。
| 对比 | Zustand | Redux Toolkit | Jotai |
|---|---|---|---|
| 代码量 | 极少 | 中等 | 少 |
| 学习曲线 | 极低 | 中等 | 低 |
| Boilerplate | 无 | 有 | 无 |
| 需要Provider | 不需要 | 需要 | 不需要 |
| 中间件 | 支持 | 支持 | 有限 |
| 体积 | ~1KB | ~11KB | ~3KB |
核心用法
// 安装:npm install zustand
// store/useCounterStore.ts
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'
interface CounterState {
count: number
increment: () => void
decrement: () => void
reset: () => void
}
// 基础用法
const useCounterStore = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 })
}))
// 带持久化和DevTools
const useStore = create<CounterState>()(
devtools(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 })
}),
{ name: 'counter-storage' } // localStorage key
)
)
)
// 在组件中使用
function Counter() {
const { count, increment, decrement, reset } = useCounterStore()
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={reset}>Reset</button>
</div>
)
}
// 只订阅需要的字段(性能优化)
function Count() {
const count = useCounterStore((state) => state.count)
return <p>{count}</p>
}
// 复杂状态示例:Todo Store
interface TodoStore {
todos: Todo[]
filter: 'all' | 'active' | 'done'
addTodo: (text: string) => void
toggleTodo: (id: string) => void
deleteTodo: (id: string) => void
setFilter: (filter: TodoStore['filter']) => void
filteredTodos: () => Todo[]
}
interface Todo {
id: string
text: string
done: boolean
}
const useTodoStore = create<TodoStore>((set, get) => ({
todos: [],
filter: 'all',
addTodo: (text) => set((state) => ({
todos: [...state.todos, { id: crypto.randomUUID(), text, done: false }]
})),
toggleTodo: (id) => set((state) => ({
todos: state.todos.map(t => t.id === id ? { ...t, done: !t.done } : t)
})),
deleteTodo: (id) => set((state) => ({
todos: state.todos.filter(t => t.id !== id)
})),
setFilter: (filter) => set({ filter }),
// 派生状态
filteredTodos: () => {
const { todos, filter } = get()
switch (filter) {
case 'active': return todos.filter(t => !t.done)
case 'done': return todos.filter(t => t.done)
default: return todos
}
}
}))
// 异步操作
interface UserStore {
users: User[]
loading: boolean
error: string | null
fetchUsers: () => Promise<void>
}
const useUserStore = create<UserStore>((set) => ({
users: [],
loading: false,
error: null,
fetchUsers: async () => {
set({ loading: true, error: null })
try {
const res = await fetch('/api/users')
const users = await res.json()
set({ users, loading: false })
} catch (error) {
set({ error: 'Failed to fetch', loading: false })
}
}
}))
推荐资源
| 资源 | 说明 |
|---|---|
| Zustand官方文档 | GitHub pmndrs/zustand |
| Zustand教程 | Jack Herrington YouTube |