Preact 表格 Store 订阅模式:深入解析 `SubscribePropsWithStore` 类型
Preact 表格 Store 订阅模式深入解析SubscribePropsWithStore类型【免费下载链接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table项目地址: https://gitcode.com/gh_mirrors/ta/table在 TanStack Table 的 Preact 适配器tanstack/preact-table中SubscribePropsWithStore是订阅完整表格状态full table state这一核心场景的类型契约。它定义了以table.store为数据源、以显式selector投影状态、并以children渲染函数消费选中值的完整 props 结构是构建精细化响应式表格 UI如行选择、分页、过滤等高性能交互的关键类型之一。读完本文你将掌握SubscribePropsWithStore的三个属性source/selector/children各自的作用与约束它与SubscribePropsWithSource系列类型的区别以及它在useTable与Subscribe组件中的真实调用方式与性能优化实践。类型定义速览SubscribePropsWithStore定义在 packages/preact-table/src/Subscribe.ts声明如下type SubscribePropsWithStore TFeatures extends TableFeatures, TSelected, { source: SubscribeSourceTableStateTFeatures selector: (state: TableStateTFeatures) TSelected children: ((state: TSelected) ComponentChildren) | ComponentChildren }对应生成的 API 文档位于 docs/framework/preact/reference/type-aliases/SubscribePropsWithStore.md。类型参数类型参数约束含义TFeaturesextends TableFeatures当前表格启用的功能集features如行选择、分页、过滤等用于推导TableState的具体形状TSelected无selector投影返回的选中值类型决定children渲染函数收到的参数类型三个必填属性属性类型说明sourceSubscribeSourceTableStateTFeatures订阅的数据源固定为完整表格状态table.storeselector(state) TSelected从完整TableState中投影出所需切片选中值变化浅比较时触发重渲染children((state) ComponentChildren) \| ComponentChildren渲染子内容传函数时接收selector的返回值也可直接传静态 JSX属性语义详解source完整表格状态订阅源source的类型是SubscribeSourceTableStateTFeatures。SubscribeSourceTValue是一个联合类型定义见 Subscribe.ts:11 及 SubscribeSource.mdtype SubscribeSourceTValue | AtomTValue | ReadonlyAtomTValue | StoreTValue | ReadonlyStoreTValue在 store 模式下source传入的是table.store——这是由 TanStack Store 支撑的、保存完整TableState的响应式 store。table.store.state是当前值的快照useTable.ts:35中有明确注释警告其只读快照、非响应式订阅入口而正确的订阅方式正是通过本类型描述的Subscribe组件或useSelector(table.store, selector)。selector强制显式投影防止误订阅整个 storeselector: (state: TableStateTFeatures) TSelected接收完整的TableState并返回任意投影值。在 store 模式下selector是必填的源码注释给出了设计意图Subscribe.ts:27-29Required in store mode so you never accidentally subscribe to the whole store without an explicit projection.也就是说直接订阅table.store而不做投影会让组件在任何状态变化时都重渲染。显式selector强制开发者声明关心的状态切片配合源码中useSelector传入的{ compare: shallow }浅比较Subscribe.ts:114-120只有当选中值的浅比较结果发生变化时才触发重渲染。children函数式渲染子children支持两种形式函数(state: TSelected) ComponentChildren接收selector选中的值。这是最常用的形式组件内部会以props.children(selected)方式调用Subscribe.ts:122-124。静态 JSX直接传入ComponentChildren此时不消费选中值。与SubscribePropsWithSource系列的分工SubscribePropsWithStore只是SubscribeProps联合类型的一个分支Subscribe.ts:61-68type SubscribePropsTFeatures, TSelected, TSourceValue | SubscribePropsWithStoreTFeatures, TSelected | SubscribePropsWithSourceIdentityTSourceValue | SubscribePropsWithSourceWithSelectorTSourceValue, TSelected三条分支的定位差异详见 SubscribeProps.md 与 SubscribePropsWithSource.md分支类型source 类型selector适用场景SubscribePropsWithStoretable.store完整状态必填一次性订阅多个状态切片或需要组合状态SubscribePropsWithSourceIdentity单个 atom / store省略恒等投影订阅某个完整值如table.atoms.rowSelectionSubscribePropsWithSourceWithSelector单个 atom / store可选从单一数据源投影出更细的值在useTable与Subscribe中的实际用法方式一table.Subscribe推荐useTable在创建表格实例时把Subscribe绑定到实例上useTable.ts:140-145未传source时自动回退到tableInstance.storetableInstance.Subscribe ((props: any) { return Subscribe({ ...props, source: props.source ?? tableInstance.store, }) }) as PreactTableTFeatures, TData, TSelected[Subscribe]table.Subscribe的签名在useTable.ts中通过重载overload实现useTable.ts:43-79让 JSX 上下文类型推断在两种模式下都正确工作。因此在组件中优先使用table.Subscribe——它在不传source时等价于SubscribePropsWithStore缺省 source 指向table.store传source时等价于 source 系列类型。典型用法来自 examples/preact/basic-subscribe/src/main.tsx 的完整可运行示例// 订阅完整 store投影出多个状态切片表头全选按钮 table.Subscribe selector{(state) ({ columnFilters: state.columnFilters, globalFilter: state.globalFilter, rowSelection: state.rowSelection, })} {() ( IndeterminateCheckbox checked{table.getIsAllRowsSelected()} indeterminate{table.getIsSomeRowsSelected()} onChange{table.getToggleAllRowsSelectedHandler()} / )} /table.Subscribe // 仅订阅 rowSelection atom且只投影当前行的选中值 table.Subscribe source{table.atoms.rowSelection} selector{(s) s?.[row.id]} {(isRowSelected) ( input typecheckbox checked{!!isRowSelected} / )} /table.Subscribe方式二独立Subscribe组件当table不在作用域内时可以直接从tanstack/preact-table导入Subscribe组件并显式传入source{table.store}Subscribe.ts:76-96 的官方示例import { Subscribe } from tanstack/preact-table Subscribe source{table.store} selector{(state) ({ rowSelection: state.rowSelection })} {({ rowSelection }) ( divSelected rows: {Object.keys(rowSelection).length}/div )} /Subscribe需要注意独立组件使用联合props类型而table.Subscribe采用重载签名以获得更好的 JSX 上下文类型推断源码注释明确指出这一点见 Subscribe.ts:72-74。因此在 JSX 中使用table.Subscribe是官方推荐路径独立Subscribe组件适合脱离表格实例的通用订阅场景。源码实现Subscribe组件如何工作Subscribe组件的完整实现只有寥寥几行Subscribe.ts:98-125核心依赖tanstack/preact-store的useSelectorexport function Subscribe(props: SubscribePropsTFeatures, TSelected, TSourceValue): ComponentChildren { const selected useSelector( props.source as never, props.selector as Parameterstypeof useSelector[1], { compare: shallow }, ) as TSelected return typeof props.children function ? (props.children as (state: TSelected) ComponentChildren)(selected) : props.children }关键点订阅useSelector对sourceatom 或 store建立响应式订阅浅比较compare: shallow决定何时重渲染——只有selector选中的值在浅比较下变化才触发渲染children是函数则调用并传入selected否则原样渲染。性能优化实践订阅隔离官方示例的注释basic-subscribe/src/main.tsx明确指出Subscribe/table.Subscribe是更高阶的订阅组件用来把重渲染精确限制在 Preact 组件树中需要更新的局部位置仅在遇到具体性能问题时才推荐使用。实践要点总结默认零订阅useTable(tableOptions, () null)传入空投影默认不订阅任何状态再用table.Subscribe按需订阅示例第 154 行的做法原子级订阅订阅table.atoms.rowSelection等单个 atom再投影到行级值如s?.[row.id]使勾选一行只重渲染该行组合切片订阅订阅完整 store 时用selector显式声明所需切片避免无谓的全量重渲染验证时机官方示例注释提醒要小心测试并验证它在预期时刻才重渲染main.tsx:66。该模式在仓库测试中也有充分验证packages/preact-table/tests/unit/rendering.test.tsxdescribe(table.Subscribe)验证了订阅后状态更新的渲染行为packages/preact-table/tests/unit/adapterReactivity.test.tsx验证了Subscribe两种 source 重载的桥接以及每个被选依赖各自隔离渲染周期的测试用例isolates Subscribe render cycles to each selected dependencypackages/preact-table/tests/unit/useTable.test.tsx则覆盖了table.Subscribe订阅分页状态的场景。小结SubscribePropsWithStore是 TanStack Table Preact 适配器中订阅完整表格状态场景的类型骨架source固定指向table.storeselector强制显式投影浅比较决定重渲染时机children消费选中值完成局部渲染。理解它是掌握tanstack/preact-table精细化响应式订阅、构建高性能表格交互的第一步。实际开发中优先通过table.Subscribe缺省 source 即 store 模式获得最佳类型推断需要脱离表格实例时再使用独立的Subscribe组件。 /output文章【免费下载链接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table项目地址: https://gitcode.com/gh_mirrors/ta/table创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Rome useAltText 规则:强制图片等元素提供无障碍替代文本的完整指南

Rome useAltText 规则:强制图片等元素提供无障碍替代文本的完整指南

开发工具CLILint格式化静态分析代码质量构建工具 【免费下载链接】tools Unified developer tools for JavaScript, TypeScript, and the web 项目地址: https://gitcode.com/gh_mirrors/to/tools 点击查看 免费下载 本指南以 Rome 官方 lint 规则文档 useAltText …

2026/9/22 0:15:44 阅读更多 →
CANN ops-nn 算子 aclnnMaxPool3D 完整指南:两段式接口、三种 Padding 模式与 NPU 端到端调用实战

CANN ops-nn 算子 aclnnMaxPool3D 完整指南:两段式接口、三种 Padding 模式与 NPU 端到端调用实战

CANN ops-nn 算子 aclnnMaxPool3D 完整指南:两段式接口、三种 Padding 模式与 NPU 端到端调用实战 【免费下载链接】ops-nn 本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-nn 导读 …

2026/9/20 20:52:16 阅读更多 →
内存充足却卡死?从事件日志到硬件超频的系统排查指南

内存充足却卡死?从事件日志到硬件超频的系统排查指南

如果你的电脑配置了 64GB 内存,平时根本没跑到过半,结果最近两三周里莫名其妙卡死了 6 次——鼠标还能动,系统就是没反应,动两下直接黑屏或者屏幕定格,重启之后一切又正常,任务管理器里内存占用也不高&…

2026/9/21 22:02:20 阅读更多 →

最新新闻

3个坑让仙台地图渲染崩盘?这份保姆级教程救你

3个坑让仙台地图渲染崩盘?这份保姆级教程救你

3个坑让仙台地图渲染崩盘?这份保姆级教程救你 上周给一个医疗SaaS项目做区域数据可视化,客户点名要集成“仙台地图”组件。我信心满满,结果第一版代码跑起来,控制台直接炸出一屏红字,StackTrace 长得像天书,滚动条都拉不到底。…

2026/9/22 1:02:19 阅读更多 →
3个新手避坑点:北京积分落户新政策源码级拆解与帧对比选型

3个新手避坑点:北京积分落户新政策源码级拆解与帧对比选型

3个新手避坑点:北京积分落户新政策源码级拆解与帧对比选型 看了一堆教程还是不会写项目?别怪自己笨,是你没搞懂底层逻辑。北京积分落户新政策的核心其实就是一本动态账本,很多新手在报名材料清单整理时栽跟头,不是因为材料不全,而是因为没看懂“加权逻…

2026/9/22 1:02:19 阅读更多 →
自动重拨最佳实践

自动重拨最佳实践

3个坑让你告别手动重拨:新手避坑指南 学会语法却不知怎么搭项目,是很多刚入行同学的通病。特别是处理网络不稳定场景时,盯着报错日志发呆,只会手动刷新页面。自动重拨机制看似简单,实则暗藏玄机,稍不留神就陷入死循环。 入口定位:为什么你需要它…

2026/9/22 1:02:19 阅读更多 →
商标宝注册全流程解析与避坑最佳实践

商标宝注册全流程解析与避坑最佳实践

商标宝注册全流程解析与避坑最佳实践 刚拿到商标宝查询结果,或者在提交注册时看到那一长串红色的 StackTrace 报错,是不是瞬间大脑宕机?很多人以为这是系统崩溃,其实是你的申请文件触发了审查系统的硬性拦截。别慌,这行干久了就知道,报错不…

2026/9/22 1:02:19 阅读更多 →
3个实战项目拆解ustcmail,彻底搞懂USTC邮件系统

3个实战项目拆解ustcmail,彻底搞懂USTC邮件系统

3个实战项目拆解ustcmail,彻底搞懂USTC邮件系统 看了一堆教程还是不会写项目?这是大多数应届生在准备大厂面试时的真实困境。你背了无数八股文,刷了上百道算法题,但一旦面试官问起“你做过什么实战项目”,你的大脑瞬间空白。特别是当涉及到…

2026/9/22 1:02:19 阅读更多 →
高速工具钢源码解析: 3步搞定版本API变更坑

高速工具钢源码解析: 3步搞定版本API变更坑

高速工具钢源码解析: 3步搞定版本API变更坑 版本升级后 API 全变了,这是转岗工程师最崩溃的瞬间。你刚把旧版逻辑跑通,新版文档却换了天,报错堆栈像天书。别慌,我们直接拆解 高速工具钢 相关的底层逻辑,通过 源码解析 找到不变的内核。…

2026/9/22 1:01:18 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →