在 React 开发中,状态管理一直是核心问题之一。早期我们依赖 React 自带的 useState 和 useReducer,但随着项目规模的扩大,跨组件通信、状态共享、性能优化等问题逐渐显现。
为了解决这些问题,社区出现了很多状态管理方案,如 Redux、MobX、Context API + useReducer、Recoil、Jotai,以及今天我们重点要讲的——Zustand。
一、Zustand 是什么?
Zustand(发音为 /ˈzuːstænd/,德语“状态”的意思)是由 Piotr Witek 和 React Hot Team 开发的一个轻量级状态管理库,专为 React 设计,支持 React 16.8+(即支持 Hook 的版本)。
📦 官网地址:
二、Zustand 的核心特点
| 特性 | 描述 |
|---|---|
| 轻量无依赖 | 仅 1KB 左右,不依赖任何第三方库 |
| API 简洁 | 一个 create 函数搞定所有 |
| 无需 Provider | 不需要包裹 <Provider>,直接导入 store 使用 |
| 跨组件共享状态 | 支持多个组件共享状态,无需层层传递 |
| 中间件支持 | 支持 DevTools、日志、持久化、undo/redo 等扩展 |
| React Hook 风格 | 使用 useStore Hook 订阅状态,响应式更新 |
| 支持 TypeScript | 类型推导友好,开箱即用 |
| 可拆分 Store | 支持模块化管理多个 store,避免臃肿 |
三、为什么选择 Zustand?
✅ 相比 Redux:
- 无需
action、reducer、dispatch、connect、Provider等复杂概念 - 更简洁的 API,更少的样板代码
- 更适合中小型项目,快速上手
✅ 相比 Context + useReducer:
- 更好的性能优化(只订阅需要的状态)
- 更清晰的状态更新逻辑
- 更容易跨组件共享状态
✅ 相比 MobX:
- 无侵入性,不需要
@observable、@action等装饰器 - 更轻量,更容易理解
- 更适合 React Hook 风格
四、Zustand 核心使用方式
1. 安装
npm install zustand
# 或
yarn add zustand
2. 创建 Store
// store/useCounterStore.js
import create from 'zustand';
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
3. 在组件中使用
// Counter.jsx
import useCounterStore from './store/useCounterStore';
function Counter() {
const count = useCounterStore((state) => state.count);
const increment = useCounterStore((state) => state.increment);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={increment}>Increment</button>
</div>
);
}
📌
useCounterStore是一个 Hook,传入一个 selector 函数,用于订阅 store 中的部分状态。
五、Zustand 的工作原理
Zustand 的核心机制非常简单高效:
- 创建一个全局状态对象
- 通过
useStoreHook 订阅状态 - 当状态更新时,自动触发使用该状态的组件重新渲染
它使用了 React 的 useSyncExternalStore(React 18)或 useEffect(React 17)来监听状态变化,确保组件只在状态相关部分变化时更新,性能非常优秀。
六、Zustand 的高级用法
1. 持久化状态(如 localStorage)
import create from 'zustand';
import { persist } from 'zustand/middleware';
const useAuthStore = create(persist(
(set) => ({
user: null,
login: (user) => set({ user }),
logout: () => set({ user: null }),
}),
{
name: 'auth-storage', // localStorage key
getStorage: () => localStorage,
}
));
2. DevTools 调试支持
import { devtools } from 'zustand/middleware';
const useCounterStore = create(devtools((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
})));
3. 日志中间件(Logger)
import { devtools, persist, createLogger } from 'zustand/middleware';
const useCounterStore = create(
devtools(createLogger((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
})))
);
4. 模块化管理多个 Store
// store/useUserStore.js
const useUserStore = create(() => ({ user: null, setUser: (user) => {} }));
// store/useCartStore.js
const useCartStore = create(() => ({ items: [], addItem: (item) => {} }));
// 组件中按需引入
import useUserStore from './store/useUserStore';
import useCartStore from './store/useCartStore';
七、Zustand 与 React Query 的关系
虽然 Zustand 是一个状态管理工具,但 React Query 是一个数据获取和缓存库,两者并不冲突,可以结合使用:
- Zustand 管理全局状态(如用户登录、UI 状态)
- React Query 管理异步数据(如接口请求、缓存、刷新)
function useUserData() {
const { data } = useQuery(['user'], fetchUser);
const setUser = useUserStore((state) => state.setUser);
useEffect(() => {
if (data) setUser(data);
}, [data, setUser]);
return data;
}
八、Zustand 的局限性
| 局限点 | 说明 |
|---|---|
| 不适合超大型项目 | 如果项目非常复杂,Redux Toolkit 或 MobX 可能更适合 |
| 不支持异步 action 自动处理 | 需要手动管理异步逻辑(如 loading、error 状态) |
| 无内置 undo/redo 功能 | 需要借助中间件实现 |
九、Zustand 适合的项目类型
| 项目类型 | 是否推荐 |
|---|---|
| 小型项目(1-5 个页面) | ✅ 非常推荐 |
| 中型项目(5-20 个页面) | ✅ 推荐 |
| 大型项目(20+ 页面) | ⚠️ 视情况而定 |
| React Native 项目 | ✅ 推荐 |
| 需要快速开发的项目 | ✅ 推荐 |
| 需要 TypeScript 支持的项目 | ✅ 推荐 |
| 需要 DevTools、持久化等扩展功能的项目 | ✅ 推荐 |
十、总结:Zustand 的核心价值
Zustand 是 React 状态管理的“瑞士军刀”——轻量、灵活、强大。
| 优势 | 说明 |
|---|---|
| 轻量无依赖 | 极小体积,无外部依赖 |
| API 简洁 | 一个 create 函数搞定所有 |
| Hook 风格 | 完全契合 React 的 Hook 体系 |
| 性能优秀 | 精准更新,只重渲染依赖状态的组件 |
| 拓展性强 | 支持 DevTools、持久化、日志等中间件 |
| 学习成本低 | 没有 Redux 的 action、reducer 等复杂概念 |
✅ 推荐搭配使用
| 工具 | 用途 |
|---|---|
zustand/middleware | DevTools、持久化、日志等 |
react-query | 数据请求、缓存、刷新 |
immer | 支持不可变更新语法 |
TypeScript | 类型安全 |
Vite / Next.js / React Native | 构建工具或平台 |
🎯 结语
如果你正在寻找一个轻量、易用、灵活、性能优秀的状态管理方案,Zustand 是一个非常值得尝试的选择。
记住一句话: “Zustand 把状态管理变得更像写业务逻辑,而不是写样板代码。 ”