关于 tanstack-store
TanStack Store 是轻量、与框架无关的响应式状态管理库,适用于需要共享状态和派生计算的应用开发者。它提供 Store、Derived、Effect 与批量更新,并有多个框架适配器。
主要功能
- 01框架无关的响应式状态容器
- 02惰性计算派生值
- 03依赖变化时运行副作用
- 04批量更新并合并通知
- 05提供多种框架适配器
适用场景
- 01在组件间共享响应式状态
- 02从多个状态源计算派生值
- 03批量执行相关状态更新
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill tanstack-store安装后在 Claude Code 中输入/tanstack-store确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/core-concepts.mdderived-state.mdreact-integration.md详细介绍
TanStack Store
概览
TanStack Store 是一个轻量、与框架无关的响应式状态管理库,支持类型安全的更新、派生计算、批量修改和副作用管理。它在内部为 TanStack 库提供核心能力,也可作为独立的状态解决方案使用。提供适用于 React、Vue、Solid、Angular 和 Svelte 的框架适配器。
核心原语:
- Store — 响应式容器,提供
setState、订阅和生命周期钩子 - Derived — 延迟计算的值,可跟踪 Store/Derived 依赖
- Effect — 在依赖发生变化时触发的副作用运行器
- batch — 将多次更新合并,使订阅者只触发一次
适用场景: 在多个组件之间共享响应式状态、根据多个 Store 派生/计算值、批量更新状态、可跨 React/Vue/Solid/Angular/Svelte 复用的框架无关状态逻辑,以及作为 Redux/Zustand/MobX 的轻量替代方案。
不适用场景: 服务端状态和缓存(TanStack Query)、带中间件的复杂规范化状态(Redux Toolkit)、表单状态管理(TanStack Form)、简单的组件本地状态(useState/useSignal)。
主要特性:
- 包体积小巧,零依赖
- 不可变更新模型(始终从
setState返回新的引用) - Derived 值采用延迟求值(发生变化后,仅在访问时重新计算)
- Derived 和 Effect 的挂载/卸载生命周期需显式管理(不会自动清理)
安装
| Package | Use Case |
|---|---|
@tanstack/store | 与框架无关的核心 |
@tanstack/react-store | React 适配器(重新导出核心) |
@tanstack/vue-store | Vue 适配器 |
@tanstack/solid-store | Solid 适配器 |
@tanstack/angular-store | Angular 适配器 |
@tanstack/svelte-store | Svelte 适配器 |
框架包会重新导出核心的 Store、Derived、Effect 和 batch —— 只需安装对应的框架包,无需同时安装两者。
快速参考
| 模式 | API | 关键点 |
|---|---|---|
| 创建存储 | new Store(initialState, options?) | 泛型参数为 TState 和 TUpdater |
| 读取状态 | store.state | 同步属性访问 |
| 上一个状态 | store.prevState | 上次调用 setState 前的值 |
| 更新状态 | store.setState((prev) => newState) | 接受更新函数或直接传入值 |
| 订阅 | store.subscribe(listener) | 返回取消订阅函数 |
| 派生值 | new Derived({ deps, fn }) | 依赖项变化时惰性重新计算 |
| 挂载派生值 | derived.mount() | 激活依赖跟踪所必需 |
| 从派生值派生 | 在另一个 deps 中嵌套 Derived | 构成计算图 |
| 批量更新 | batch(() => { ... }) | 所有更新完成后只通知一次订阅者 |
| 副作用 | new Effect({ deps, fn, eager? }) | 依赖项变化时运行 fn |
| 挂载副作用 | effect.mount() | 开始监听所必需 |
| React 绑定 | useStore(store, selector?) | 仅在选定值变化时重新渲染 |
| 浅比较 | useStore(store, selector, shallow) | 对结构相等的对象避免重新渲染 |
| 生命周期:订阅 | onSubscribe 选项 | 首个订阅者加入时触发,最后一个订阅者离开时清理 |
| 生命周期:更新 | onUpdate 选项 | 每次状态变化后触发 |
| 自定义更新器 | updateFn 选项 | 替换默认的 setState 行为 |
| 上一个依赖项 | fn: ({ prevDepVals }) | 比较当前与上一个依赖项的值 |
| 访问依赖项值 | fn: ({ currDepVals }) | 数组顺序与 deps 声明顺序一致 |
常见错误
| 错误 | 正确模式 |
|---|---|
未挂载就读取 derived.state | 访问状态前调用 derived.mount() |
| 忘记卸载派生值/副作用 | 保存清理函数,并在清理时调用 |
多次调用 setState,但未进行批处理 | 将相关更新包装在 batch() 中,以避免中间重新计算 |
在 useStore 中选择对象时未使用 shallow | 将 shallow 作为第三个参数传入,以避免不必要的重新渲染 |
| 直接修改状态对象 | 始终从 setState 更新器返回一个新对象 |
| 在渲染期间订阅但未清理 | 在 React 中使用 useStore hook,而不是手动调用 subscribe |
| 在 React 组件内创建存储 | 在组件外实例化存储,或将其放在 ref/useState 中 |
| 未在 Derived 中包含所有依赖项 | 在 deps 数组中列出每个 Store/Derived 依赖项 |
| 在父级之后挂载 Derived 依赖项 | 先挂载叶级依赖项,再挂载父级 Derived 值 |
将 @tanstack/store 直接用于 React | 安装重新导出核心功能的 @tanstack/react-store |
委派
- 服务端状态和缓存:如果有
tanstack-queryskill,请委派给它。否则,建议使用:npx skills add oakoss/agent-skills --skill tanstack-query - React 组件模式:委派给特定框架的 skill,处理组件架构
- 表单状态管理:如果有
tanstack-formskill,请委派给它。否则,建议使用:npx skills add oakoss/agent-skills --skill tanstack-form - 查询模式发现:使用
ExploreAgent 在代码库中查找示例 - 代码审查:委派给
code-reviewerAgent 审查 store 架构
参考资料
评论
支持 Markdown