从 Pinia 到 Zustand:我在 React 里复刻了一套用户状态管理

我是小ao,一名大二学生,正在用 React + TypeScript 开发一个名为"面试克星"的 AI 面试准备平台。在此之前,我用 Vue 3 + Pinia 独立完成过一个全栈论坛项目。切换到 React 技术栈后,我遇到的第一个需要"翻译"的概念就是状态管理。

为什么要用状态管理库?

在"面试克星"里,用户登录后,导航栏需要显示用户名,个人主页需要展示和编辑用户资料,路由守卫需要判断登录状态。如果只用组件内部的 useState,这些数据会在组件间传递得乱七八糟。我需要一个全局的、能让所有组件共享的用户状态中心。

在 Vue 里我有 Pinia,在 React 里我选了 Zustand------它轻量、API 简单,而且和 Pinia 的心智模型非常接近。

Zustand vs Pinia:核心概念对照

概念 Pinia (Vue) Zustand (React)
创建 Store defineStore('auth', { state, actions }) create<State>((set) => ({ ... }))
读取状态 const auth = useAuthStore() const user = useUserStore((s) => s.user)
修改状态 直接修改 this.user = xxx 调用 set({ user: xxx }) 传入新状态
异步操作 actions 里写 async 函数 在 Store 内部直接写 async 函数

最大的差异在于状态的更新方式。Pinia 借助 Vue 的响应式系统,你可以直接修改状态(像改普通对象一样)。Zustand 则遵循 React 的不可变数据原则,你必须通过 set 返回一个新的状态对象。

我设计的 useUserStore

我的 Store 需要管理用户信息、JWT Token、登录状态,并提供登录、注册、退出、更新信息的方法。在用 TypeScript 之后,我发现必须先定义一个 interface,把数据和方法签名提前写好。这比 JS 版本的 Pinia 多了一道工序,但它成了我 Store 的自文档。

typescript 复制代码
interface UserState {
  user: { _id: string; username: string; email: string; ... } | null;
  token: string | null;
  isLogin: boolean;
  login: (email: string, password: string) => Promise<void>;
  register: (email: string, password: string) => Promise<void>;
  loginOut: () => void;
  updateUser: (fields: Partial<...>) => Promise<void>;
}

初始化时,我会从 localStorage 读取 token,如果存在就将 isLogin 设为 true。这样刷新页面后,登录状态不会丢失。

login 方法通过 axios 向后端发送请求,拿到 tokenuser 后,用 set({ user, token, isLogin: true }) 一次性更新 Store。register 同理,成功后只更新 user,因为注册后不自动登录。

updateUser 是我在个人主页实现内联编辑时加的。用户修改年龄、性别等字段后,我会先调后端 PUT /api/users/me 接口,成功后再用 set 更新本地 Store。这保证了前端展示与数据库同步。

那一层 interface,是负担还是助手?

刚开始写 TS 时,我觉得每个 Store 都要写一个长长的接口很麻烦。后来有一次,我在组件里不小心写错了状态名(user.username 打成了 user.userName),TypeScript 立刻在编辑器里划了红线。我突然明白了------这层 interface 不是负担,它是在我出错之前就帮我揪出 bug 的"安全网"。

从 Pinia 到 Zustand,换的是框架,不变的是对"集中管理状态、驱动视图更新"这一模式的理解。真正花时间的,从来不是学习某个库的 API,而是理解"状态管理"本身。

相关推荐
陆枫Larry41 分钟前
Astro 是什么
前端
是立不是利2 小时前
写给设计师的 CSS 博客美学指南
前端·css
默_笙3 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师3 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen3 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员
a1117763 小时前
Shirone 二次元博客主题 开源
前端·开源
IT_陈寒3 小时前
Python的切片赋值把我坑惨了,这不是bug是特性
前端·人工智能·后端
掘金酱3 小时前
【社区公告】致每一位掘友:关于这次调整, 想再说几句
前端·人工智能
CoderLiu3 小时前
程序化工具调用(PTC)与动态工作流引擎:深入大模型工具调用的架构演进与实践
前端·人工智能·后端