68 - Zustand 状态管理教程

适用人群:React 开发者
难度:低
预计学习时间:3-5小时

什么是 Zustand?

Zustand 是 React 生态中最轻量的状态管理库,API 极简,无样板代码,无需 Provider,比 Redux 简单 10 倍。

对比ZustandRedux ToolkitJotai
代码量极少中等
学习曲线极低中等
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
返回首页