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

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

React 项目中,如果你觉得 Redux 太"仪式化"、Recoil 太"脑洞"、MobX 太"魔法"...

那你大概率会爱上 Zustand

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

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

perl 复制代码
npm create vite@latest
# 选择 react-ts 模板

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

css 复制代码
npm i react-router-dom
npm install tailwindcss @tailwindcss/vite
npm install antd

配置 Tailwind

index.css

scss 复制代码
@import "tailwindcss";

配置 alias:@ → src

vite.config.ts

javascript 复制代码
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

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

typescript 复制代码
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


四、在组件中使用状态

javascript 复制代码
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 文件!)


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

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

typescript 复制代码
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。

persist 中间件能力:

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

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

dart 复制代码
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 状态变化。


七、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 Toolkit Zustand
学习曲线 有设计理念,略重 极快,几分钟上手
核心思想 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

代码写起来爽就完事了

延伸阅读

相关推荐
前端不太难5 小时前
从 Navigation State 反推架构腐化
前端·架构·react
前端程序猿之路6 小时前
Next.js 入门指南 - 从 Vue 角度的理解
前端·vue.js·语言模型·ai编程·入门·next.js·deepseek
大布布将军6 小时前
⚡️ 深入数据之海:SQL 基础与 ORM 的应用
前端·数据库·经验分享·sql·程序人生·面试·改行学it
川贝枇杷膏cbppg6 小时前
Redis 的 RDB 持久化
前端·redis·bootstrap
JIngJaneIL7 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
天外天-亮7 小时前
v-if、v-show、display: none、visibility: hidden区别
前端·javascript·html
jump_jump7 小时前
手写一个 Askama 模板压缩工具
前端·性能优化·rust
be or not to be7 小时前
HTML入门系列:从图片到表单,再到音视频的完整实践
前端·html·音视频
90后的晨仔8 小时前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端
沿着路走到底8 小时前
JS事件循环
java·前端·javascript