React Context 在全局状态管理中是内置方案,但存在根本问题:context 值变化时,所有消费者都会重渲染,即使用户只关心其中一个字段。拆分多个 context 可以缓解,但代码迅速膨胀。
Zustand 通过基于选择器的订阅机制解决此问题:组件只订阅自己需要的 state slice,其他字段更新时不会触发自身重渲染。API 简洁,迁移成本低。
核心对比与关键模式
Context 的重渲染问题:
任何用户状态(user/preferences/notifications)变化都会导致所有 useContext(UserContext) 的组件重渲染。
Zustand 的选择器订阅:
每个组件只在其订阅的字段变化时重渲染。例如 Header 只监听 user,NotificationBell 只监听 notifications。
生产模式(TypeScript + Persist)
使用 create<State>() 创建 store,搭配 persist 中间件自动同步 localStorage。partialize 控制持久化字段,临时状态(如 jobId)不持久化。
Server Component 集成
服务端数据通过 props 传递,客户端 UI 状态由 Zustand 管理。
计算状态与 useShallow
通过选择器计算派生数据(如 pendingCount)。useShallow 防止对象选择器因浅比较失效导致不必要重渲染。
何时仍用 Context
一次性初始化(主题、会话)cache不变时;库自带的 context API(React Query、React Router);组件树极小且同时渲染。
迁移清单
创建 store → 替换 useContext 为 useMyStore(selector) → 移除 Provider → 对象字段用 useShallow → 删除 context 文件。
测试
直接调用 getState() 和 setState(),无需挂载组件。
Zustand 核心优势:细粒度订阅、简洁 API、良好 TypeScript 支持、不受组件树限制(可在 WebSocket 等非 React 环境直接调用 getState 更新状态)。对于 Next.js App Router 中大部分客户端状态需求,Zustand 是比 Context 更优的默认选择。
#Nextjs #Zustand #React #状态管理 #开发者 #工具 #状态管理库
📢 频道:@DevToolboxHub
@DevToolboxHub