mcpField
N
nextjs-zustand

nextjs-zustand

github.com/fusengine开发3576 次安装1 周前更新
代码仓库

关于 nextjs-zustand

面向 Next.js 16 App Router 应用中使用 Zustand v5 管理客户端状态的技能,重点介绍基于 Context 的请求隔离 Store、SSR 水合、中间件和文件组织。

主要功能

  1. 01介绍 Zustand v5 Store 创建语法
  2. 02使用基于 Context 的 Store 隔离请求
  3. 03涵盖中间件组合
  4. 04处理持久化与 SSR 水合
  5. 05按功能模块组织 Store

适用场景

  1. 01管理多个客户端组件共享的状态
  2. 02处理 UI 状态持久化与水合
  3. 03组织 App Router 项目的 Store
  4. 04避免选择器引发不必要的重渲染

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fusengine/claude-plugins --skill nextjs-zustand

安装后在 Claude Code 中输入/nextjs-zustand确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
auto-selectors.md
hydration.md
installation.md
middleware.md
migration-v5.md
nextjs-integration.md
reset-state.md
slices.md
store-patterns.md
subscribe-api.md
testing.md
typescript.md

详细介绍

在 Next.js 16 App Router 中实现 Zustand v5 客户端状态管理:v5 柯里化语法(`create()((set) => ({...}))`)、基于 Context 的存储(使用 `zustand/vanilla` 中的 `createStore` 和 `useRef` 构建;在 App Router 中这是必需的,可避免不同请求之间状态泄漏——绝不要使用全局存储),以及中间件组合(devtools → persist → immer;顺序会影响 TypeScript 类型)。

涵盖 persist 中间件的 skipHydration,以及在 useEffect 中手动重新水合以避免 SSR 不匹配;用于数组/对象选择器的 useShallow,以及 SOLID 文件组织(store.ts、store-provider.tsx、use-store.ts)。明确说明 Zustand 仅用于客户端组件——绝不用于服务端组件(应直接在那里获取数据),也绝不用于持久化身份验证令牌(请使用 httpOnly Cookie)。不涵盖服务端状态缓存(参见 nextjs-tanstack-query)。

Next.js 16 中的 Zustand

基于 React 18+ useSyncExternalStore 的精简、可扩展状态管理。

Agent 工作流(必须遵循)

在进行任何实现之前,并行启动 3 个 Agent,每个各调用一次 Agent,并指定一个 name:

  1. fuse-ai-pilot:explore-codebase - 分析现有存储和状态模式
  2. fuse-ai-pilot:research-expert - 通过 Context7/Exa 验证最新的 Zustand v5 文档
  3. mcp__context7__query-docs - 检查中间件和 TypeScript 模式

实现后,运行 fuse-ai-pilot:sniper 进行验证。


概述

适用场景
  • 在 Next.js App Router 应用中管理客户端状态
  • 仅需在客户端组件之间共享全局状态
  • 将状态持久化到 localStorage/sessionStorage
  • 构建 UI 状态(模态框、侧边栏、主题、购物车)
  • 用于替代复杂状态管理中的 React Context
为什么选择 Zustand v5
特性优势
极简 API简单的 create() 函数,无需样板代码
原生支持 React 18使用 useSyncExternalStore,无需垫片
TypeScript 优先柯里化模式可实现完整类型推断
中间件栈可组合使用 devtools、persist、immer
包体积压缩后约 2KB,是最小的状态库
无需 Provider可直接访问存储,无需 Context 包装器

关键规则

  1. 仅限客户端组件 - 绝不在服务端组件中使用 Zustand
  2. App Router 使用 Context 模式 - 避免使用全局存储(隔离请求)
  3. 数组/对象使用 useShallow - 避免不必要的重新渲染
  4. persist 使用 skipHydration - SSR 兼容所必需
  5. v5 柯里化语法 - create<State>()((set) => ({...}))
  6. SOLID 路径 - 存储放在 modules/[feature]/src/stores/

SOLID 架构

模块结构

按功能模块组织存储:

  • modules/cores/stores/ - 共享存储(主题、UI)
  • modules/auth/src/stores/ - 身份验证状态
  • modules/cart/src/stores/ - 购物车状态
  • modules/[feature]/src/interfaces/ - 存储类型
文件组织
文件用途
store.ts使用 create() 创建存储(最多 40 行,遵循所有者规则)
store.interface.tsTypeScript 接口
store-provider.tsxContext Provider(App Router)
use-store.ts带选择器的自定义 Hook

核心概念

创建存储(v5 语法)

TypeScript 类型推断需要使用双括号。柯里化模式可确保完整的类型安全。

基于 Context 的存储

对于 Next.js App Router,应将存储封装在 Context 中,以防止请求间共享。使用 zustand/vanilla 中的 createStore,并通过 useRef 进行初始化。

中间件组合

按以下顺序叠加中间件:devtools → persist → immer。顺序会影响 TypeScript 类型。

水合处理

在 persist 中间件中使用 skipHydration: true。在 useEffect 中手动重新水合,以避免 SSR 不匹配。


参考指南

需求参考
初始设置installation.md
Store 模式store-patterns.md
SSR/水合hydration.md
中间件middleware.md
Next.js App Routernextjs-integration.md
TypeScripttypescript.md
Slices 模式slices.md
自动选择器auto-selectors.md
重置状态reset-state.md
订阅 APIsubscribe-api.md
测试testing.md
从 v4 迁移到 v5migration-v5.md

最佳实践

  1. 选择器模式 - 始终使用 useStore((s) => s.field) 以提升性能
  2. useShallow - 使用 useShallow 包装数组/对象选择器,避免重新渲染
  3. 分离 Store - 每个领域使用一个 Store(auth、cart、ui、theme)
  4. 将服务端数据存放在其他位置 - 使用 TanStack Query 管理服务端状态
  5. 仅在开发环境使用 DevTools - 使用 process.env 检查包裹 devtools
  6. 精简持久化内容 - 只持久化必要字段,绝不持久化令牌

禁止的模式

模式原因替代方案
在 App Router 中使用全局 Store用户之间共享请求基于 Context 的 Store
在 Server Components 中使用 ZustandRSC 中没有 React hooks直接获取数据
持久化认证令牌安全漏洞httpOnly cookies
对象选择器未使用 useShallow过度重新渲染useShallow(selector)
v4 语法TypeScript 类型推断失效v5 柯里化语法 create<T>()()

评论

支持 Markdown