如何用结构共享与 select 细粒度订阅减少 TanStack Router 组件重复渲染
如何用结构共享与 select 细粒度订阅减少 TanStack Router 组件重复渲染【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/router如果你用 TanStack Routertanstack/react-router把分页、筛选条件等状态放在 URL search params 里可能会遇到这种情况某个组件只用到了search.foo但用户修改search.bar后它也跟着重新渲染。TanStack Router 提供了两个互补的手段来解决这个问题**细粒度选择器select**让组件只订阅 router state 的一个子集**结构共享structural sharing**让select返回的对象在值没变时保持引用稳定。本文按先用select缩小订阅范围再按需开启 structural sharing的顺序给出完整配置路径全部内容来自仓库内的 Render Optimizations 指南。重复渲染来自哪里先明确文档给出的两个触发点这决定了后两步优化分别针对什么订阅了不需要的状态。像useSearch、useRouterState这类 hook 返回完整的 search 对象或 router stateURL 中任意 search param 变化都会让订阅它的组件重新渲染。select每次返回新对象。当select函数返回对象时每次调用都会产生一个新的对象引用即使内部字段值完全没变组件也会重新渲染。另外要注意结构共享默认是关闭的文档说明这是为了保持向后兼容且这一点在 v2 中可能会改变见 Render Optimizations。所以在做任何订阅优化之前先确认你的项目没有开启它。第一步用select缩小订阅范围useSearch支持select选项函数接收 search 对象返回值直接作为 hook 的返回值。官方文档给出的示例是一个带foo、bar两个 search params 的details路由// component wont re-render when bar changes const foo Route.useSearch({ select: ({ foo }) foo })文档对上面这行的行为判定是当导航从/details?foof1barb1到/details?foof1barb2时组件不会因为bar的变化而重新渲染。Route.useSearch()是路由上的类型化 hook如果在别的组件里读取某条路由的 search params使用顶层useSearch并传入from选项useSearch hook APIimport { useSearch } from tanstack/react-router const selected useSearch({ from: /posts/$postId, select: (search) search.postView, })select不是useSearch独有的。useRouterState同样提供select与structuralSharing两个选项例如只订阅 locationconst selected useRouterState({ select: (state) state.location, })useRouterState hook API 中还有一条建议如果只是要拿当前 location 或 matches优先考虑useLocation、useMatches这类 hook它们比直接读useRouterState更轻量。此外仓库 API 文档中useMatches、useChildMatches、useParentMatches、useParams、useLoaderData、useLoaderDeps、useMatch等 hook 也都定义了structuralSharing选项订阅 router state 的其他位置可以按同样思路处理。到这一步能解决订阅面过大的问题。但如果你希望select返回对象而不是单个字段就会撞上第二个触发点const result Route.useSearch({ select: (search) { return { foo: search.foo, hello: hello ${search.foo}, } }, })文档明确指出这样写的话select每次调用都返回一个新对象组件会因此重新渲染。解决办法是下一步的 structural sharing。第二步开启 structural sharing 让 select 返回的对象保持引用稳定TanStack Router 对 search params 本来就内置了结构共享导航只改bar时search.foo保持引用稳定只有search.bar被替换见 Render Optimizations。对于select返回的值需要显式开启结构共享文档给了两种互斥的开启方式方式一在 router 选项中全局默认开启const router createRouter({ routeTree, defaultStructuralSharing: true, })defaultStructuralSharing是RouterOptions的一个可选项类型boolean默认值为false作用是为细粒度选择器默认启用 structural sharing见 RouterOptions API。方式二按 hook 调用点单独开启const result Route.useSearch({ select: (search) { return { foo: search.foo, hello: hello ${search.foo}, } }, structuralSharing: true, })structuralSharing选项的定义是配置select返回值是否启用 structural sharing见 useSearch hook API 的opts.structuralSharing一节。选择建议如果整个应用里大量 hook 都需要select返回对象用方式一全局开启更省事如果只是个别订阅点需要用方式二局部开启避免影响其他调用点的默认行为。如何验证优化是否生效文档给出的可观察判定如下可直接用于核对订阅收窄生效按第一步的示例导航只修改未被订阅的参数如bar时使用该select订阅的组件不应重新渲染。这是文档对select: ({ foo }) foo的直接行为描述。结构共享生效导航/details?foof1barb1→/details?foof1barb2时search.foo引用保持不变只有search.bar被替换。类型层面对开启 structural sharing 的调用做约束如果你让select返回 class 实例如new Date()并开启structuralSharing: trueTypeScript 会直接报错const result Route.useSearch({ select: (search) { return { date: new Date(), } }, structuralSharing: true, })也就是说非 JSON 兼容的返回值在编译期就能被拦截这本身也是一次免费的检查。限制与回退structural sharing 只支持 JSON 兼容的数据。开启后不能用select返回 class 实例之类的值上面的new Date()例子在类型上会报错这是预期行为而不是 bug。如果按方式一在 router 选项里全局开启了defaultStructuralSharing个别必须返回非 JSON 数据或不想做结构共享的调用点可以单独设置structuralSharing: false来规避。默认关闭且 v2 可能改变文档明确说明结构共享默认关闭是为了向后兼容this may change in v2。升级版本时建议重新确认defaultStructuralSharing的默认值。完成上述两步后订阅面过大和select返回新对象两个触发点都已被覆盖前者用select解决后者用defaultStructuralSharing或逐点的structuralSharing解决。更多 hook 的select/structuralSharing细节可查阅 Render Optimizations 指南 与docs/router/api/router/下各 hook 的 API 文档。【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于 Azure IoT Hub 与 Functions 构建双语通用翻译器:IoT-For-Beginners 消费者课程结课实战

基于 Azure IoT Hub 与 Functions 构建双语通用翻译器:IoT-For-Beginners 消费者课程结课实战

基于 Azure IoT Hub 与 Functions 构建双语通用翻译器:IoT-For-Beginners 消费者课程结课实战 【免费下载链接】IoT-For-Beginners 12 Weeks, 24 Lessons, IoT for All! 项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners 导读 本文面向…

2026/11/9 4:02:59 阅读更多 →
optimizerDuck 需要联网吗?Windows优化工具的离线运行与更新检查完整说明

optimizerDuck 需要联网吗?Windows优化工具的离线运行与更新检查完整说明

optimizerDuck 需要联网吗?Windows优化工具的离线运行与更新检查完整说明 【免费下载链接】optimizerDuck Free, open-source Windows optimization tool for performance, privacy, and simplicity. 项目地址: https://gitcode.com/GitHub_Trending/op/optimizer…

2026/10/24 8:27:08 阅读更多 →
豆包AI微信机器人接入实战:5分钟把微信机器人接上大模型

豆包AI微信机器人接入实战:5分钟把微信机器人接上大模型

豆包AI微信机器人接入实战:5分钟把微信机器人接上大模型 【免费下载链接】wechat-bot 🤖 Multi-platform IM AI Agent for Telegram, WhatsApp, Lark, and WeChat. Connects ChatGPT / Claude / Kimi / DeepSeek / Ollama / Pi for auto-replies, commun…

2026/10/22 19:14:58 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻