Zustand 教程

教程概览

欢迎来到全面的 Zustand 教程!本指南将带你从入门到精通,教你关于 Zustand 状态管理的一切。

第 1 课:Zustand 简介

Zustand 是一个轻量级的 React 状态管理库,它提供:

  • 简单直观的 API
  • 无需样板代码
  • 出色的 TypeScript 支持
  • 卓越的性能和自动优化
  • 小巧的包体积(小于 1KB)

为什么选择 Zustand?

与其他状态管理解决方案(如 Redux 或 MobX)相比,Zustand 提供了更简单的 API 和更少的样板代码,同时保持了强大的功能和卓越的性能。

第 2 课:创建你的第一个 Store

让我们创建一个简单的待办事项列表应用程序:

import { create } from 'zustand'

interface Todo {
  id: number
  text: string
  completed: boolean
}

interface TodoStore {
  todos: Todo[]
  addTodo: (text: string) => void
  toggleTodo: (id: number) => void
  removeTodo: (id: number) => void
}

const useTodoStore = create<TodoStore>((set) => ({
  todos: [],
  addTodo: (text) =>
    set((state) => ({
      todos: [
        ...state.todos,
        { id: Date.now(), text, completed: false }
      ]
    })),
  toggleTodo: (id) =>
    set((state) => ({
      todos: state.todos.map((todo) =>
        todo.id === id
          ? { ...todo, completed: !todo.completed }
          : todo
      )
    })),
  removeTodo: (id) =>
    set((state) => ({
      todos: state.todos.filter((todo) => todo.id !== id)
    })),
}))

Lesson 3: Using the Store in Components

function TodoList() {
  const todos = useTodoStore((state) => state.todos)
  const addTodo = useTodoStore((state) => state.addTodo)
  const toggleTodo = useTodoStore((state) => state.toggleTodo)
  const removeTodo = useTodoStore((state) => state.removeTodo)
  const [input, setInput] = useState('')

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (input.trim()) {
      addTodo(input)
      setInput('')
    }
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Add a todo..."
        />
        <button type="submit">Add</button>
      </form>
      
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id)}
            />
            <span style={{ 
              textDecoration: todo.completed ? 'line-through' : 'none' 
            }}>
              {todo.text}
            </span>
            <button onClick={() => removeTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  )
}

第 4 课:异步操作和高级模式

异步操作

在 Zustand 中处理异步操作非常简单 - 只需将你的操作设为 async!

const useStore = create((set) => ({
  data: null,
  loading: false,
  error: null,
  fetchData: async () => {
    set({ loading: true, error: null })
    try {
      const response = await fetch('https://api.example.com/data')
      const data = await response.json()
      set({ data, loading: false })
    } catch (error) {
      set({ error: error.message, loading: false })
    }
  }
}))

计算属性

使用选择器创建派生状态:

const useStore = create((set) => ({
  todos: [],
  // ... actions
}))

// In your component
const completedCount = useStore(
  (state) => state.todos.filter(t => t.completed).length
)
const totalCount = useStore((state) => state.todos.length)

下一步

继续学习以下主题:

  • 用于持久化和开发工具的中间件
  • 测试 Zustand store
  • 高级 TypeScript 模式
  • 性能优化技巧
  • 与其他库集成