Zustand 状态管理快速入门:React 中最简洁的全局状态方案

约 5 分钟阅读

在 React 的世界里,状态管理一直是核心话题。虽然有 Redux、MobX 等强大的库,但它们通常伴随着大量的模板代码 (boilerplate) 和复杂的概念。React Context API 虽然简单,但在处理频繁更新或大型状态时又容易引发性能问题。

有没有一种方案,既像 Redux 一样强大,又像 Context 一样易用?

答案就是 Zustand

Zustand 是一个基于 Flux 思想的、极简的 React 状态管理库。它的名字在德语中就是“状态”的意思,其核心理念就是:用最少的代码,做最多的事


核心概念:创建 Store

Zustand 的所有魔法都始于 create 函数。你只需要用它来创建一个 “Store”,这个 Store 就是一个包含了你的状态和操作方法的 Hook。

让我们以本博客的搜索弹窗为例。我们之前用 Zustand 解决了弹窗被多次渲染的问题,其核心 store 的定义如下:

typescript
// src/store/search.ts
import { create } from 'zustand'

// 1. 定义你的状态和操作的接口 (TypeScript)
interface SearchState {
  isOpen: boolean
  onOpen: () => void
  onClose: () => void
  toggle: () => void
}

// 2. 使用 create 函数创建 store
export const useSearchStore = create<SearchState>((set, get) => ({
  // 状态 (State)
  isOpen: false,

  // 操作 (Actions)
  onOpen: () => set({ isOpen: true }),
  onClose: () => set({ isOpen: false }),
  toggle: () => set({ isOpen: !get().isOpen }),
}))

就这么简单!我们已经创建了一个全局可用的 useSearchStore Hook。它包含了:

  • isOpen: 一个布尔类型的状态。
  • onOpen, onClose, toggle: 三个用于改变 isOpen 状态的函数。

set 函数用于更新状态,而 get 函数可以让你在 action 内部获取当前的状态。


在组件中使用 Store

在任何 React 组件中,你都可以像使用普通 Hook 一样使用 useSearchStore,来订阅和操作状态。

jsx
// src/components/search-command.tsx
"use client"

import { useSearchStore } from "@/store/search"

export function SearchCommand() {
  // 从 store 中解构出你需要的数据和方法
  const { isOpen, onOpen, onClose } = useSearchStore()

  return (
    <>
      {/* 点击按钮时,调用 store 中的 onOpen 方法 */}
      <Button onClick={onOpen}>打开搜索</Button>

      {/* 将 store 中的 isOpen 和 onClose 状态直接绑定到弹窗组件 */}
      <CommandDialog onOpenChange={onClose} open={isOpen}>
        {/* ... */}
      </CommandDialog>
    </>
  )
}

Zustand 的美妙之处在于:

  • 无需 Provider:你不需要像 Context API 那样在组件树的顶层包裹一个 <Provider>
  • 精准更新:只有使用了特定状态的组件才会在该状态变更时重新渲染。例如,如果另一个组件只使用了 onOpen 方法而没有使用 isOpen 状态,那么当 isOpen 变化时,那个组件并不会重新渲染,从而获得了极佳的性能。

进阶:中间件 (Middleware)

Zustand 还支持通过中间件来增强功能。最常用的一个就是 persist,它可以轻松地将你的状态持久化到 localStoragesessionStorage 中。

typescript
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

// 假设我们要保存用户的主题偏好
interface ThemeState {
  theme: 'light' | 'dark'
  setTheme: (theme: 'light' | 'dark') => void
}

export const useThemeStore = create(
  persist<ThemeState>(
    (set) => ({
      theme: 'light',
      setTheme: (newTheme) => set({ theme: newTheme }),
    }),
    {
      name: 'theme-storage', // localStorage 中的 key
      storage: createJSONStorage(() => localStorage), // 指定使用 localStorage
    }
  )
)

现在,theme 状态会在用户刷新页面后依然保持不变。

总结

Zustand 以其极简的 API、强大的功能和出色的性能,成为了现代 React 开发中全局状态管理的首选方案之一。它完美地平衡了易用性和灵活性,让你能更专注于业务逻辑,而不是状态管理的繁文缛节。

相关文章