🐻 Zustand 使用指南:从 0 到精通的最快路线

219 阅读3分钟

“长得可爱?别被骗了。Zustand 是 React 状态管理里唯一一个又小、又狠、又快的小熊。”

image.png React 项目中,如果你觉得 Redux 太“仪式化”、Recoil 太“脑洞”、MobX 太“魔法”…
那你大概率会爱上 Zustand

✔ “你需要多少状态管理,就给你多少,不多不少”。

一、初始化项目(最简 + 最现代栈)

npm create vite@latest
# 选择 react-ts 模板

安装 react-router-dom(v7)、tailwindcss、Ant Design:

npm i react-router-dom
npm install tailwindcss @tailwindcss/vite
npm install antd

配置 Tailwind

index.css

@import "tailwindcss";

配置 alias:@ → src

vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      "@": "/src",
    },
  },
});

tsconfig.app.json

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

到此为止,一个现代化 React 工程初始化完毕。


🐻 二、主角登场:Zustand

官网:
zustand.docs.pmnd.rs/getting-sta…

Zustand 的特点:

❗ “每一个 store 就是一个能直接使用的 hook,不需要 Provider,不需要 context,不需要 boilerplate。”

安装:

npm install zustand

三、创建一个最简单的 Zustand Store

src/store/counter.ts

import { create } from "zustand";

type State = {
  bears: number;
};

type Actions = {
  increasePopulation: () => void;
  removeAllBears: () => void;
  updateBears: (newBears: number) => void;
};

const useCounterStore = create<State & Actions>((set) => ({
  bears: 0,
  increasePopulation: () =>
    set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
  updateBears: (newBears: number) => set({ bears: newBears }),
}));

export default useCounterStore;

你没有看错:

✔ 一个 store 就是一个 hook

✔ 可以随时在任何地方使用,不用 Provider

✔ set 会自动合并对象,不会覆盖整个 state


四、在组件中使用状态

import useCounterStore from "@/store/counter";
import { Button, Space } from "antd";

export default function Counter() {
  const bears = useCounterStore((state) => state.bears);
  
  return (
    <>
      <div>当前 bears 数量: {bears}</div>
      <Space size="large">
        <Button
          type="primary"
          onClick={() => useCounterStore.getState().increasePopulation()}
        >
          增加
        </Button>

        <Button
          type="primary"
          onClick={() => useCounterStore.getState().removeAllBears()}
        >
          重置
        </Button>
      </Space>
    </>
  );
}

注意:

Zustand 不需要 provider

useStore.getState() 可以在任何地方使用(事件回调/异步逻辑/非 React 文件!)


image.png

五、持久化:刷新浏览器也不丢数据

Zustand 的 persist 中间件,可以直接把数据存到 localStorage / sessionStorage。

import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";

export const usePersistCounterStore = create<{
  persistCounter: number;
  addPersistCounter: () => void;
}>()(
  persist(
    (set, get) => ({
      persistCounter: 0,
      addPersistCounter: () =>
        set({ persistCounter: get().persistCounter + 1 }),
    }),
    {
      name: "food-storage",
      storage: createJSONStorage(() => sessionStorage),
    }
  )
);

上述仓库数据源即保存在sessionStorage。

image.png

persist 中间件能力:

  • 自动序列化 JSON
  • 支持 localStorage / sessionStorage
  • 支持自定义 storage(IndexDB / 自己封装)

六、接入 Devtools:可视化查看 Zustand 状态(强推)

import { devtools } from "zustand/middleware";

export const usePersistCounterStore = create<{
  persistCounter: number;
  addPersistCounter: () => void;
}>()(
  devtools(
    persist(
      (set, get) => ({
        persistCounter: 0,
        addPersistCounter: () =>
          set({ persistCounter: get().persistCounter + 1 }),
      }),
      {
        name: "food-storage",
        storage: createJSONStorage(() => sessionStorage),
      }
    )
  )
);

安装 Redux Devtools 插件即可直接看到 Zustand 状态变化。

image.png


七、subscribe-with-selector:精确订阅(性能神器)

Zustand 默认按 selector 返回值变化触发渲染。
如果你想在组件外订阅变化(比如 WebSocket 更新 / 定时器),可以使用 subscribeWithSelector 中间件。

🔥 官网推荐写大型项目必须配这个。

文档:
zustand.docs.pmnd.rs/middlewares…


⚔ 八、为什么 Zustand 被称为小体积却“有爪子”?

它解决了 React 状态管理的三大噩梦:

❌ 僵尸子组件(Zombie Child)

❌ React 18 更新丢失

❌ 多渲染器(如 React Native)上下文错乱

Zustand 内部使用 Proxy + 订阅机制,完全避开了这些问题。


九、Redux vs Zustand 简要对比

特性Redux ToolkitZustand
学习曲线有设计理念,略重极快,几分钟上手
核心思想Flux 单向数据流Hooks + minimal store
需要 Provider✔ 必须❌ 不需要
持久化需要插件内置中间件
Devtools官方支持✔ 直接兼容
适合规模中大型复杂业务中小业务 + 大型高性能项目

结论:

Zustand 用最少的 API 做了最强的状态管理,是目前 React 应用里最好用的轻量级全局状态方案,没有之一。


🏁 十、总结:为什么你应该在新项目里选 Zustand?

  • 无 Provider、无样板代码、无复杂心智负担
  • 逻辑可以写在 React 外
  • 极轻量(≈1KB),性能极强
  • 官方中间件已经覆盖大部分需求(persist / devtools / immer / subscribe-with-selector)
  • 完美兼容 React 18、React Native、SSR
  • 写起来像 useState,却是全局 store

代码写起来爽就完事了

延伸阅读