TanStack Table React 中 SubscribePropsWithSource 类型解析:细粒度订阅 Atom 与 Store 的强类型方案
TanStack Table React 中 SubscribePropsWithSource 类型解析细粒度订阅 Atom 与 Store 的强类型方案【免费下载链接】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 TableReact 适配层tanstack/react-table公开类型SubscribePropsWithSourceTSourceValue, TSelected展开讲解如何通过sourceselectorchildren三要素订阅单个 Atom 或 Store原样订阅或投影订阅并剖析其与SubscribePropsWithSourceIdentity、SubscribePropsWithSourceWithSelector、SubscribeProps的类型层级关系以及底层useSelector 浅比较的实现原理。读完本文你将掌握在 React 表格中按需订阅table.atoms.rowSelection、table.optionsStore等单一数据源、避免整表重渲染的完整实践方案。一、类型定义一个联合类型的“二选一”SubscribePropsWithSource定义在 react-table/src/Subscribe.ts本质是一个可辨识联合discriminated unionexport type SubscribePropsWithSourceTSourceValue, TSelected TSourceValue | SubscribePropsWithSourceIdentityTSourceValue | SubscribePropsWithSourceWithSelectorTSourceValue, TSelected它对应Subscribe组件的两种调用形态不传selector——命中SubscribePropsWithSourceIdentity原样订阅整个源的值传入selector——命中SubscribePropsWithSourceWithSelector订阅源值的投影结果。官方类型注释明确建议当省略selector时优先直接使用SubscribePropsWithSourceIdentity或SubscribePropsWithSourceWithSelector因为二选一联合在省略selector的场景下类型推断更清晰见 Subscribe.ts:57-61。类型参数参数默认值含义TSourceValue无默认值必填被订阅数据源Atom/Store中存储的值的类型TSelected TSourceValue经过selector投影后 children 实际接收的值的类型注意TSelected的默认值正是TSourceValue当不使用投影时children 拿到的就是源值本身因此不需要单独声明第二个类型参数。二、拆解两个分支变体1. SubscribePropsWithSourceIdentity原样订阅定义见 react-table/src/Subscribe.ts:41-45export type SubscribePropsWithSourceIdentityTSourceValue { source: SubscribeSourceTSourceValue selector?: undefined children: ((state: TSourceValue) ReactNode) | ReactNode }三个关键点sourceSubscribeSourceTSourceValue一个 Atom、只读 Atom、Store 或只读 Storeselector?: undefined被强制声明为undefined从类型层面禁止传入 selectorchildren既可以是接收源值的函数(state: TSourceValue) ReactNode也可以是静态的ReactNode。官方文档对其语义的说明是订阅某个源的完整值例如table.atoms.rowSelection或table.optionsStore省略selector等价于恒等选择器identity selector——children 直接收到TSourceValue见 SubscribePropsWithSourceIdentity.md。2. SubscribePropsWithSourceWithSelector投影订阅定义见 react-table/src/Subscribe.ts:51-55export type SubscribePropsWithSourceWithSelectorTSourceValue, TSelected { source: SubscribeSourceTSourceValue selector: (state: TSourceValue) TSelected children: ((state: TSelected) ReactNode) | ReactNode }与 Identity 形态的唯一区别是selector为必填函数它接收源值TSourceValue返回投影后的TSelected而 children 收到的是TSelected。这一形态适合“数据源很大但只需要其中一小块”的场景例如从整张行选择表中投影出某一行是否被选中。三、source 的合法取值SubscribeSource两种形态共享source字段其类型SubscribeSourceTValue定义在 react-table/src/Subscribe.ts:13-14export type SubscribeSourceTValue | AtomTValue | ReadonlyAtomTValue | StoreTValue | ReadonlyStoreTValue即四种来自tanstack/react-store的响应式数据源均可直接作为source传入类型说明AtomTValue可变原子状态ReadonlyAtomTValue只读原子状态StoreTValue可变存储ReadonlyStoreTValue只读存储在 TanStack Table React 的实际 API 中最常见的两个source就是table.atoms.rowSelectionAtom 形态行选择状态table.optionsStoreStore 形态表格配置项存储。这解释了为什么该类型命名为 “WithSource”——它面向的是单个源atom 或 store而非整个table.store。四、与 SubscribeProps 的关系类型金字塔SubscribePropsWithSource不是孤立的类型它被更大的联合类型SubscribeProps收编Subscribe.ts:66-73export type SubscribeProps TFeatures extends TableFeatures, TSelected unknown, TSourceValue unknown, | SubscribePropsWithStoreTFeatures, TSelected | SubscribePropsWithSourceIdentityTSourceValue | SubscribePropsWithSourceWithSelectorTSourceValue, TSelected也就是说Subscribe组件的完整 props 集合包含三种订阅模式Store 模式SubscribePropsWithStore订阅table.store完整表格状态selector接收完整TableStateTFeatures并必填防止开发者无意中订阅整个 store见 Subscribe.ts:20-34源 Identity 模式本文主题的恒等订阅源投影模式本文主题的投影订阅。本文讨论的SubscribePropsWithSource恰好覆盖其中的后两种。五、底层实现useSelector 浅比较类型层之外Subscribe组件的运行时实现Subscribe.ts:122-149揭示了“为什么细粒度订阅不会引发整树重渲染”export function SubscribeTSourceValue( props: SubscribePropsWithSourceIdentityTSourceValue, ): ReturnTypeFunctionComponent export function SubscribeTSourceValue, TSelected( props: SubscribePropsWithSourceWithSelectorTSourceValue, TSelected, ): ReturnTypeFunctionComponent // ... Store 模式重载 ... export function SubscribeTFeatures extends TableFeatures, TSelected, TSourceValue( props: SubscribePropsTFeatures, TSelected, TSourceValue, ): ReturnTypeFunctionComponent { const selected useSelector( props.source, props.selector as Parameterstypeof useSelector[1], { compare: shallow }, ) as TSelected return typeof props.children function ? (props.children as (state: TSelected) ReactNode)(selected) : props.children }实现要点重载优先源码为三种形态分别声明了函数重载identity、with-selector、store保证 JSX 场景下的上下文类型推断尽可能精确统一的订阅协议Atom 与 Store 共享tanstack/react-store的选择协议所以source可以统一交给useSelector处理代码中仅需对联合参数做一次类型拓宽见 Subscribe.ts:138-141 的注释浅比较shallow compareuseSelector使用compare: shallow只有投影结果的浅比较不等时才会触发重渲染这正是性能收益的来源children 二态分发children是函数时以投影结果为入参调用否则原样渲染静态节点。六、实战用法示例源码注释Subscribe.ts:83-120给出了四种典型写法这里结合本文类型逐一解读。示例 1Identity 形态——整块订阅行选择 Atom// 省略 selector等价于恒等投影 Subscribe source{table.atoms.rowSelection} {(rowSelection) div{Object.keys(rowSelection).length} rows selected/div} /Subscribe命中SubscribePropsWithSourceIdentitychildren 直接拿到rowSelection对象。示例 2投影形态——订阅某一行的选中状态Subscribe source{table.atoms.rowSelection} selector{(rowSelection) rowSelection?.[row.id]} {(selected) tr>Subscribe source{table.store} selector{(state) ({ rowSelection: state.rowSelection })} {({ rowSelection }) ( divSelected rows: {Object.keys(rowSelection).length}/div )} /Subscribe注意此处selector必填Store 模式约束且按浅比较语义返回新对象字面量也符合预期的触发条件。示例 4table.Subscribe——实例方法形态table.Subscribe selector{(state) ({ rowSelection: state.rowSelection })} {({ rowSelection }) ( divSelected rows: {Object.keys(rowSelection).length}/div )} /table.SubscribeuseTable返回的表格实例会把Subscribe绑定为实例方法见 useTable.ts:169-174并自动注入source table.store。源码注释Subscribe.ts:80-82特别提醒如果使用useTable产生的table.Subscribe应优先用这个实例 API——它有更完善的重载JSX 上下文类型推断比独立组件的联合 props 类型更友好。七、何时选用哪种形态决策小结场景推荐形态原因需要 Atom/Store 的完整值SubscribePropsWithSourceIdentity不传 selector类型最简TSelected TSourceValue自动推断只需要源值的一部分/变换结果SubscribePropsWithSourceWithSelector必传 selector投影后按浅比较精确控制重渲染范围订阅整个table.store的状态切片Store 模式SubscribePropsWithStore或直接使用table.Subscribeselector 必填强制显式投影防止订阅整棵状态树从类型设计上可以推断项目刻意用“selector?: undefined”与“selector: fn”两个形态把“要不要投影”编码进了类型系统让误用例如传了 selector 却以为没传在编译期即被拦截这是 TanStack Table React 在订阅 API 上“类型即文档”的体现。更多相关类型可继续参阅 SubscribeProps、SubscribeSource 与 SubscribePropsWithStore或直接阅读完整实现 packages/react-table/src/Subscribe.ts。【免费下载链接】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),仅供参考

相关新闻

Shopee af-ac-enc-dat 参数剖析:从动态签名到合规采集的避坑指南

Shopee af-ac-enc-dat 参数剖析:从动态签名到合规采集的避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:27:22 阅读更多 →
深入解析 Airbyte 声明式连接器 source-nebius-ai:基于 Low-Code CDK 的 Manifest 驱动数据同步

深入解析 Airbyte 声明式连接器 source-nebius-ai:基于 Low-Code CDK 的 Manifest 驱动数据同步

深入解析 Airbyte 声明式连接器 source-nebius-ai:基于 Low-Code CDK 的 Manifest 驱动数据同步 【免费下载链接】airbyte Open-source data movement for ELT pipelines and AI agents — from APIs, databases & files to warehouses, lakes, and AI applicat…

2026/9/21 2:26:21 阅读更多 →
ADManager Plus:企业级AD域图形化管理与PowerShell深度集成平台

ADManager Plus:企业级AD域图形化管理与PowerShell深度集成平台

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:26:21 阅读更多 →

最新新闻

STM32+MPU6050固定翼增稳飞控:从姿态解算到PID调参与救机

STM32+MPU6050固定翼增稳飞控:从姿态解算到PID调参与救机

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 3:03:40 阅读更多 →
开始使用 VUX 之前:前置知识、工具链与工程化准备

开始使用 VUX 之前:前置知识、工具链与工程化准备

UI组件前端 【免费下载链接】vux Mobile UI Components based on Vue & WeUI 项目地址: https://gitcode.com/gh_mirrors/vu/vux 点击查看 免费下载 在正式使用 VUX(Vue & WeUI 移动端 UI 组件库)之前,你不需要是一位资深…

2026/9/21 3:03:40 阅读更多 →
VitePress 接入 Headless CMS:基于动态路由与数据加载器的完整实践指南

VitePress 接入 Headless CMS:基于动态路由与数据加载器的完整实践指南

前端文档 【免费下载链接】vitepress Vite & Vue powered static site generator. 项目地址: https://gitcode.com/gh_mirrors/vi/vitepress 点击查看 免费下载 导读 本文讲解如何将 VitePress 与各类 Headless CMS(无头 CMS)对接&…

2026/9/21 3:03:40 阅读更多 →
反激变压器设计全流程:12V/1A宽压输入算例详解

反激变压器设计全流程:12V/1A宽压输入算例详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 3:03:40 阅读更多 →
杰理AW33N系列BLE 6.0芯片选型指南:AW332A/AW333A/AW336A/AW338A对比与避坑

杰理AW33N系列BLE 6.0芯片选型指南:AW332A/AW333A/AW336A/AW338A对比与避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 3:03:40 阅读更多 →
KubeSphere 仓库中的 go-fuzz-headers:用字节驱动的 Go 模糊测试辅助库

KubeSphere 仓库中的 go-fuzz-headers:用字节驱动的 Go 模糊测试辅助库

后端云原生容器编排微服务 【免费下载链接】kubesphere kubesphere/kubesphere: KubeSphere 是一个开源的企业级容器平台,构建于 Kubernetes 之上,提供全栈化容器管理能力,包括服务治理、DevOps、微服务治理、监控告警、日志查询等功能&#…

2026/9/21 3:02:40 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/9/20 0:00:46 阅读更多 →

月新闻

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

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

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

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

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

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

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

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

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

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