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),仅供参考
企业数字化 ERP 产品动态
相关推荐
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:48
CodeIgniter 3.0.3 升级至 3.0.4 完整指南:文件替换流程、核心变更与源码解读 CodeIgniter 3.0.3 升级至 3.0.4 完整指南:文件替换流程、核心变更与源码解读 【免费下载链接】CodeIgniter Open Source PHP Framework (originally from EllisLab) 项目地址: https://gitcode.com/gh_mirrors/co/CodeIgniter
本指南对应 CodeIgniter 官方升… · 2026/9/21 2:27:48
开源生态技术水位线:如何用周刊校准真实技术信号 /* 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:08:56
TL082CDR运放选型与电路设计实战指南 /* 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:08:56
芯片选型不是参数对比,而是系统性工程决策方法 /* 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:08:56
Ollama+DeepSeek+Dify本地化部署:打造私有AI工作站实战指南 /* 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:07:56
Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化 直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡… · 2026/9/21 0:02:39
Word表格编号全攻略:从列表编号到题注交叉引用 写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技… · 2026/9/21 0:02:39
从第一个站到第二个站:独立开发者的静态网站选型与落地实践 1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&… · 2026/9/20 0:00:41
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:18
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,… · 2026/9/21 0:00:18