尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Preact Table 细粒度状态订阅:SubscribeProps 类型别名与 Subscribe 组件全面解析
Preact Table 细粒度状态订阅SubscribeProps 类型别名与 Subscribe 组件全面解析【免费下载链接】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/preact-table 构建高性能表格时如何在组件树中精准控制重渲染范围是处理上万行数据时的关键优化手段。本文围绕官方 API 参考文档中的SubscribeProps类型别名定义于 packages/preact-table/src/Subscribe.ts展开完整讲解它的三种联合变体、类型参数含义以及它如何驱动Subscribe组件实现只订阅所需状态、只在需要处重渲染的细粒度订阅能力。读完本文你将掌握 store 模式与 source 模式的选型依据、selector 投影的正确写法并能在实际项目中复刻官方示例的订阅优化模式。一、SubscribeProps 是什么一种可订阅对象的联合类型SubscribeProps是 preact-table 暴露给Subscribe组件的 props 类型。它是一个判别联合discriminated union根据是否传selector、source指向 store 还是普通 atom/store让 TypeScript 能自动收窄合法参数组合type SubscribePropsTFeatures, TSelected, TSourceValue | SubscribePropsWithStoreTFeatures, TSelected | SubscribePropsWithSourceIdentityTSourceValue | SubscribePropsWithSourceWithSelectorTSourceValue, TSelected;三种变体的设计意图源码注释直接写明SubscribePropsWithStore订阅table.store完整表格状态selector 接收完整 TableStateSubscribePropsWithSourceIdentity订阅某个 source 的完整值如table.atoms.rowSelection或table.optionsStore省略 selector 等价于恒等选择器children 直接收到TSourceValueSubscribePropsWithSourceWithSelector从 sourceatom 或 store中投影出需要的子值。三个变体的完整定义位于 SubscribePropsWithStore.md、SubscribePropsWithSourceIdentity.md、SubscribePropsWithSourceWithSelector.md。此外文档中还有另一个聚合别名SubscribePropsWithSource见 SubscribePropsWithSource.md它把后两种source 模式再合并成identity 或 projected两类从侧面印证了 source 模式下 selector 是可选的。二、类型参数逐个拆解SubscribeProps声明了三个类型参数均有默认值使用时通常由 JSX 上下文自动推断类型参数约束默认值含义TFeaturesextends TableFeatures无当前表格启用的功能特性集合如 rowSelection、pagination 等用于限定 TableState 的形状TSelected—unknownselector 投影后的返回值类型即 children 收到的数据形状TSourceValue—unknownsource 中存储的原始值类型atom 或 store 的值类型其中TFeatures来自tanstack/table-core的TableFeatures这正是 table-core 通过 feature 组合机制推导状态类型的基础。TSelected与TSourceValue默认都是unknown但在实际使用中只要传了带类型的 source例如table.atoms.rowSelection其值是RowSelectionState以及显式标注返回类型的 selectorTypeScript 就能自动推断出 children 回调参数的类型。三、三种变体逐一定义与属性详解3.1 SubscribePropsWithStore订阅完整表格状态强制 selectortype SubscribePropsWithStoreTFeatures extends TableFeatures, TSelected { source: SubscribeSourceTableStateTFeatures selector: (state: TableStateTFeatures) TSelected children: ((state: TSelected) ComponentChildren) | ComponentChildren }属性要点源码位置 Subscribe.tssource必须是SubscribeSourceTableStateTFeatures即能容纳完整TableState的 atom 或 store典型值就是table.storeselector必填。源码注释特别强调Required in store mode so you never accidentally subscribe to the whole store without an explicit projection——在 store 模式下强制要求显式投影就是为了防止你无意识地把整个 store 订阅进来导致频繁重渲染children可以是函数(state) ComponentChildren也可以直接是静态的ComponentChildren此时组件依然会订阅但渲染内容不依赖选中值常用于订阅副作用场景。3.2 SubscribePropsWithSourceIdentity订阅 source 完整值省略 selectortype SubscribePropsWithSourceIdentityTSourceValue { source: SubscribeSourceTSourceValue selector?: undefined children: ((state: TSourceValue) ComponentChildren) | ComponentChildren }属性要点Subscribe.tsselector被声明为字面量类型undefined即这个字段可以省略但一旦出现就必须是 undefined这正是判别联合用来区分两种 source 模式的标志省略 selector 时等价于恒等选择器children 收到的是 source 的整个值。3.3 SubscribePropsWithSourceWithSelector从 source 投影子值type SubscribePropsWithSourceWithSelectorTSourceValue, TSelected { source: SubscribeSourceTSourceValue selector: (state: TSourceValue) TSelected children: ((state: TSelected) ComponentChildren) | ComponentChildren }属性要点Subscribe.tsselector从TSourceValue投影出TSelected当源值变化时只有投影结果发生变化的订阅方才会重渲染配合浅比较。3.4 共同的 source 类型SubscribeSource三种变体的source字段都来自 SubscribeSourcetype SubscribeSourceTValue | AtomTValue | ReadonlyAtomTValue | StoreTValue | ReadonlyStoreTValue它统一了tanstack/preact-store中的四种可订阅对象可写/只读的 atom 与 store。table.atoms.*如rowSelection、columnFilters、globalFilter、pagination和table.store、table.optionsStore都属于这一类型的实例。四、底层实现Subscribe 组件如何消费 SubscribePropsSubscribeProps最终由Subscribe组件消费其实现位于 Subscribe.tsexport function SubscribeTFeatures extends TableFeatures, TSelected, TSourceValue( 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来自tanstack/preact-store的useSelector负责在 source 变化时驱动 Preact 重渲染浅比较去重传入{ compare: shallow }即当选中的值浅比较相等时不重渲染。这是整套细粒度订阅的性能基石——selector 每次都能返回新对象引用但浅比较后结构相同就不会触发渲染children 的双形态typeof props.children function时把选中值作为参数传入render-prop 模式否则直接渲染静态 children订阅但不消费值如示例中的触发性渲染。此外组件对外暴露了三组重载签名SubscribePropsWithSourceIdentity/SubscribePropsWithSourceWithSelector/SubscribePropsWithStore使 JSX 上下文类型推断更友好。源码注释提醒对于useTable返回的table.Subscribe应优先使用该 API它基于重载实现而独立导出的Subscribe组件使用联合 props 类型Subscribe.ts。五、实战场景从官方示例看三种订阅模式官方示例 examples/preact/basic-subscribe/src/main.tsx 完整演示了这三种模式注释明确说明其用途Subscribe/table.Subscribe 是一个高阶组件允许你订阅表格状态或单个 atom/store确保重渲染只发生在 Preact 树中确实需要的地方建议只在遇到具体性能问题时使用这些模式。5.1 store 模式表头全选复选框在表头的全选列中用table.store作为 source用 selector 只投影出影响全选状态的字段Subscribe source{table.store} selector{(state) ({ columnFilters: state.columnFilters, globalFilter: state.globalFilter, rowSelection: state.rowSelection, })} {() ( IndeterminateCheckbox checked{table.getIsAllRowsSelected()} indeterminate{table.getIsSomeRowsSelected()} onChange{table.getToggleAllRowsSelectedHandler()} / )} /Subscribestate是完整TableStateselector 把它收窄为三个相关字段的新对象浅比较保证其余状态变化不会触发此区域重渲染。5.2 source selector 模式按行订阅 rowSelection每一行的复选框只关心这一行是否被选中于是把 source 收窄到table.atoms.rowSelection再用 selector 投影出当前行的值Subscribe source{table.atoms.rowSelection} selector{(rowSelection) rowSelection[row.id]} {(isRowSelected) ( IndeterminateCheckbox checked{!!isRowSelected} disabled{!row.getCanSelect()} indeterminate{row.getIsSomeSelected()} onClick{row.getToggleSelectedHandler()} / )} /Subscribe这样切换某一行只重渲染那一行的复选框正是官方注释所说的Select only this rows selection value so toggling one row only re-renders that rows checkbox.5.3 source identity 模式全局搜索框与选中计数不带 selector 的完整值订阅适合整个值就是所需数据的场景table.Subscribe source{table.atoms.globalFilter} {(globalFilter) ( input value{globalFilter ?? } onInput{(e) table.setGlobalFilter((e.target as HTMLInputElement).value) } placeholderSearch all columns... / )} /table.Subscribe table.Subscribe source{table.atoms.rowSelection} {(rowSelection) ( div {Object.keys(rowSelection).length.toLocaleString()} of{ } {table.getPreFilteredRowModel().rows.length.toLocaleString()} Total Rows Selected /div )} /table.Subscribe这里rowSelection的类型就是RowSelectionStateTSourceValue不需要 selector 即可直接使用。5.4 性能关键实践整表也只订阅必要字段示例中连tbody都放在table.Subscribe内且 selector 只投影过滤与分页字段columnFilters、globalFilter、pagination因为行模型仅依赖这三者行选择状态则完全交给每行自己的订阅处理。同时注意示例的useTable第二参数传了() null——默认不订阅任何表格状态用 table.Subscribe 做定向更新与SubscribeProps的三种模式形成完整配合。六、使用注意事项与最佳实践结合类型定义与源码实现整理出以下实践要点store 模式必须写 selector这是类型层面强制约束必填字段也是防止性能劣化的设计护栏selector 返回值应尽量精简投影的字段越少浅比较越容易判定未变化重渲染越少返回新对象没问题浅比较会兜底恒等选择器是合法的默认source 模式省略 selector 即为恒等投影适合需要完整值如全局搜索框、状态 JSON 预览的场景优先使用table.Subscribe由useTable返回的table.Subscribe有更好的重载类型推断独立导出的Subscribe组件适合在拿不到 table 实例如 deep 子组件的场景使用静态 children 也是订阅即使 children 是普通节点而非函数组件依然通过useSelector订阅 source可用于状态变化触发副作用渲染的场景如示例表尾的全页复选框按需引入避免滥用官方示例明确建议仅在遇到具体性能问题时才使用这类细粒度模式普通场景直接订阅表状态即可。七、延伸阅读类型定义源文件packages/preact-table/src/Subscribe.ts含Subscribe组件完整实现与 JSDoc 示例三种变体独立文档SubscribePropsWithStore、SubscribePropsWithSourceIdentity、SubscribePropsWithSourceWithSelectorsource 类型定义SubscribeSource 与 SubscribePropsWithSource完整可运行示例examples/preact/basic-subscribe/src/main.tsx含 100 万行压力测试按钮可直接用npm run dev体验订阅优化效果相关类型CreateTableHookOptions、PreactTable输出文章【免费下载链接】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),仅供参考
RELATED

相关推荐

GetQzonehistory 批量导出 QQ 空间历史说说:扫码一次,动态、评论和配图全进本地

GetQzonehistory 批量导出 QQ 空间历史说说:扫码一次,动态、评论和配图全进本地

GetQzonehistory 批量导出 QQ 空间历史说说:扫码一次,动态、评论和配图全进本地 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 想翻三年前的空间动态&#xff0…

📅 2026/9/20 15:35:30
IsaacLab 远程渲染排障:3 关打通 WebRTC 可视化的完整路径

IsaacLab 远程渲染排障:3 关打通 WebRTC 可视化的完整路径

IsaacLab 远程渲染排障:3 关打通 WebRTC 可视化的完整路径 【免费下载链接】IsaacLab Unified framework for robot learning with multi-physics/renderer support 项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab 当你把 IsaacLab 训练脚本丢到…

📅 2026/9/20 15:35:30
企业架构设计实战:从业务蓝图到落地的华为方法论

企业架构设计实战:从业务蓝图到落地的华为方法论

简介:一份 105 页的 PPT 系统讲解华为企业架构设计方法与实践案例,面向企业架构师、数字化转型规划人员及 IT 治理团队,尤其适合正在推进架构蓝图落地的中大型组织参考。内容以企业架构现状分析为起点,完整覆盖业务架构、数据架构…

📅 2026/9/20 15:30:28
MORE NEWS

更多资讯

📰

OpenManus 的 config.toml 里 base_url 和 api_key 怎么填?TaoToken 这样改 [llm] 段

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

📰

RAGFlow v0.23.1:内存优化与多模态能力升级解析

1. 项目概述:RAGFlow v0.23.1的核心升级RAGFlow作为当前最热门的开源RAG(检索增强生成)框架之一,在v0.23.1版本中带来了多项关键改进。这次更新主要集中在三个方向:内存管理机制的全面优化、多模态理解能力的显著提升&…

📰

纯前端复刻折叠屏:CSS 3D变换与交互动画实战解析

1. 项目缘起:发布会上的折叠屏,为什么非要用网页做出来大家都有过这种经历:看发布会直播时,镜头给到那台折叠屏新机,开合之间屏幕带着光效展开,铰链阻尼感仿佛隔着屏幕都能听到。弹幕里全是“这也太帅了”&…

📰

基于LMD与能量熵的轴承故障诊断MATLAB实现

1. 项目背景与核心价值在工业设备状态监测领域,滚动轴承作为旋转机械的核心部件,其健康状态直接影响整机运行安全。传统振动信号分析方法在面对早期微弱故障时往往力不从心,这正是我们开发这套基于LMD(Local Mean Decomposition&a…

📰

江恩波动率副图指标源码解析:通达信ATR归一化实战

简介:通达信江恩波动率副图指标源码,以doc文档形式封装,适合股票技术分析爱好者、通达信指标编写者用于理解江恩理论在副图上的量化表达。文档内含七层波动率计算公式、红波白波EMA均线、MA5动态阈值、吸筹信号、前高突破与粉嫩次数统计等完整…

📰

MATLAB实现结构光三维重建:三频四步相移法全解析

前阵子有个研究生来问我,MATLAB做结构光三维重建到底该从哪儿入手。很多新手一上来就翻论文,三频四步相移法、多频外差、包裹相位展开这些术语看得头大,真正能跑的代码却拼不出一套。其实这套方法远没有想象中那么神秘:投影仪往被…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬