首页/新闻资讯/正文详情

Relay 14 指南:使用 useRefetchableFragment 以不同数据重取 Fragment

发布时间:2026/9/21 1:36:39 来源:云帆数科 栏目:资讯中心
Relay 14 指南:使用 useRefetchableFragment 以不同数据重取 Fragment
前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载本篇技术指南围绕 Relay 中“以不同数据重取 FragmentRefetching Fragments with Different Data”这一核心场景展开讲解如何使用useRefetchableFragmentHook 与refetchable指令让 Fragment 在保留查询上下文的前提下用一组全新的变量重新取数并渲染从而支持“切换当前选中项”“渲染不同的列表内容”等交互需求。读完本文你将掌握refetchable的适用条件、refetch函数的变量与选项语义、以及需要避开 Suspense 时的fetchQuery替代方案并能理解 Relay 编译器如何自动生成 refetch 查询的底层机制。理解“以不同数据重取 Fragment”在 Relay 中所谓refetch a fragment重取 Fragment指的是拉取一份与该 Fragment 最初渲染时不同的数据。典型场景包括改变当前选中的条目如切换商品、切换评论渲染与当前显示不同的列表内容更一般地把当前已渲染的内容过渡到新的或不同的内容。概念上这意味着把当前已渲染的 Fragment重新放到一个新的查询根query root下用不同的变量再取一次、再渲染一次。这里有一个关键前提Fragment 无法独立取数它必须依附于某个查询query。因此我们无法单独“fetch 一个 fragment”而必须借助自动生成的查询来承载重取。这正是useRefetchableFragment存在的意义配合refetchable指令Relay 编译器会自动生成一个用于重取该 Fragment 的查询Hook 返回的refetch函数则负责以新变量执行这个查询并让组件用最新数据重新渲染。使用useRefetchableFragment重取 Fragment基础示例切换评论正文的语言先看一个完整可运行的例子一个展示评论正文的CommentBody组件点击按钮即可把正文翻译成西班牙语重新取数。import type {CommentBodyRefetchQuery} from CommentBodyRefetchQuery.graphql; import type {CommentBody_comment$key} from CommentBody_comment.graphql; type Props { comment: CommentBody_comment$key, }; function CommentBody(props: Props) { const [data, refetch] useRefetchableFragmentCommentBodyRefetchQuery, _( graphql fragment CommentBody_comment on Comment # refetchable 让 Relay 为该 fragment 自动生成查询 refetchable(queryName: CommentBodyRefetchQuery) { body(lang: $lang) { text } } , props.comment, ); const refetchTranslation () { // 传入新变量调用 refetch // 它会以新变量重取 refetchable 查询 // 并用最新取回的数据更新当前组件。 refetch({lang: SPANISH}); }; return ( p{data.body?.text}/p Button onClick{() refetchTranslation()} Translate Comment /Button / ); }逐步拆解这个示例useRefetchableFragment的用法与useFragment类似参见 Fragments 一节但有几点差异它要求传入的 Fragment必须标注refetchable指令。注意refetchable只能加在“可重取”的 Fragment 上即声明在Viewer、Query类型上或声明在任何实现了Node接口即拥有id字段的类型上以及fetchable类型上。它返回一个refetch函数该函数已被 Flow 类型化其参数类型正好是生成的查询所期望的变量集合。它接受两个 Flow 类型参数第一个是自动生成查询的类型本例为CommentBodyRefetchQuery第二个通常可以被自动推断只需传下划线_。调用refetch需要两类输入第一个参数是新变量集合。传入一组新变量会让 Fragment 以这组新变量重新取数。你只需提供refetchable查询所需变量的一个子集如果 Fragment 所在类型有id字段查询会要求一个id其余变量则是 Fragment 内被传递引用的那些变量。本例中我们传入了当前评论的id和新的lang变量值以取回翻译后的正文。第二个是可选的 options 参数本例未传因此使用默认的fetchPolicystore-or-network——如果该 Fragment 的新数据已缓存则跳过网络请求参见 Reusing Cached Data For Render 相关章节。调用refetch会触发组件重新渲染并可能使useRefetchableFragment进入 Suspense参见 Loading States with Suspense。因此必须保证该组件上方有一个Suspense边界以便在取数期间展示 fallback 加载态。:::info 同样的行为也适用于usePaginationFragment返回的refetch函数参见 usePaginationFragment API。 :::refetch的变量与选项语义结合 useRefetchableFragment API 参考refetch的完整签名与语义如下variables对象用于重取refetchable查询的新变量值需与 Fragment 内引用的 GraphQL 变量一致。但有两个重要的放宽规则只需要提供打算改变的变量Fragment 引用但被省略的变量会回退到原始父查询中的值。因此若想以与最初完全相同的变量重取 Fragment直接调用refetch({})即可。对于$id变量除非你想用不同的id重取否则传id是可选的——Relay 已经知道当前渲染对象的 id。其refetch返回一个disposable对象调用disposable.dispose()可取消本次重取请求。options可选对象fetchPolicy决定是否使用缓存数据、以及在缓存可用时何时发起网络请求完整规范见 Fetch Policies。onComplete每当重取请求完成时包括任何增量数据载荷都会被调用的回调。useRefetchableFragment还具备与useFragment相同的订阅语义组件自动订阅 Fragment 数据更新如果该对象的数据在应用其他位置被更新如新取数或 mutation组件会自动用最新数据重新渲染当 Fragment 的某些数据缺失且正在被父查询获取时组件会挂起suspend。与旧版RefetchContainer的差异从useRefetchableFragment的实现历史与 API 设计看它与 class 时代的RefetchContainer相比主要有三点变化无需再手写 refetch 查询Relay 通过refetchableFragment 自动生成不再区分语义模糊的refetchVariables与renderVariables重取总是以你提供的变量正确地取数并渲染省略的变量回退到父查询原值重取总是明确地更新组件而RefetchContainer时期取决于 refetch 查询内容与 Fragment 定义的对象类型更新不一定发生。需要避开 Suspense 时fetchQuery 手动加载态有些场景下你不希望出现会隐藏已渲染内容的 Suspense fallback。此时可以用fetchQuery先把数据写入本地 Store再手动维护一个加载状态import type {CommentBodyRefetchQuery} from CommentBodyRefetchQuery.graphql; import type {CommentBody_comment$key} from CommentBody_comment.graphql; type Props { comment: CommentBody_comment$key, }; function CommentBody(props: Props) { const [data, refetch] useRefetchableFragmentCommentBodyRefetchQuery, _( graphql fragment CommentBody_comment on Comment # refetchable 让 Relay 为该 fragment 自动生成查询 refetchable(queryName: CommentBodyRefetchQuery) { body(lang: $lang) { text } } , props.comment, ); const [isRefetching, setIsRefreshing] useState(false) const refetchTranslation () { if (isRefetching) { return; } setIsRefreshing(true); // fetchQuery 会先取回查询并把数据写入 Relay store // 从而保证当我们重新渲染时数据已在缓存中、不会挂起。 fetchQuery(environment, AppQuery, variables) .subscribe({ complete: () { setIsRefreshing(false); // 查询取回 *之后*再次调用 refetch 用最新数据渲染。 // 此时该查询的数据已缓存因此用 store-only 的 // fetchPolicy 来避免挂起。 refetch({lang: SPANISH}, {fetchPolicy: store-only}); } error: () { setIsRefreshing(false); } }); }; return ( p{data.body?.text}/p Button disabled{isRefetching} onClick{() refetchTranslation()} Translate Comment {isRefetching ? LoadingSpinner / : null} /Button / ); }这个方案的关键点重取时我们自己维护isRefetching状态因为避开了挂起用它渲染忙碌指示器或类似加载 UI而不会隐藏已有内容事件处理器中先调用fetchQuery它会取回查询并把数据写入本地 Relay Store网络请求完成后再调用refetch用更新后的数据渲染与前面的示例类似此时调用refetch时该 Fragment 的数据应当已经缓存在本地 Store 中因此使用fetchPolicy为store-only只读取已缓存数据避免挂起。需要说明的是这一“避开 Suspense”的做法是当前版本的权宜方案。原文档的附注OssAvoidSuspenseNote指出在未来支持并发渲染的 React 版本中React 将提供相应选项避免挂起时用 Suspense fallback 隐藏已渲染内容。深入底层refetch是如何工作的为了把前面的实操与 Relay 的实现对上号这里结合本仓库源码梳理refetch的调用链以下文件均在 packages/react-relay 下useRefetchableFragment.js 是公开入口。它通过getFragment拿到 fragment node然后委托给内部实现useRefetchableFragmentInternal返回[fragmentData, refetch]元组。useRefetchableFragmentInternal.js 是核心实现几个值得注意的细节印证了文档语义调用refetch时源码把parentVariables、fragmentVariables与你传入的providedRefetchVariables合并得到最终的重取变量集合——这正是“省略的变量回退到父查询原值”的实现依据当 Fragment 有标识字段id等而你未显式传入时源码会从当前 Fragment 数据中读取identifierValue自动补上这就是“传id是可选的”的实现依据重取请求通过createOperationDescriptor创建强制force: true再经loadQuery启动网络请求必要时随后在渲染阶段通过QueryResource.prepare读取/等待结果并在重取查询仍在途时挂起——对应“调用 refetch 可能让组件 suspend”的行为refetch返回{dispose: disposeQuery}即文档中的 disposable可用于取消本次重取。在__DEV__模式下实现还带有一组校验函数checkSameIDAfterRefetch、checkSameTypeAfterRefetch会在重取后检查返回对象的id与__typename是否与 Store 中一致若不一致会给出 warning——这保证了以不同数据重取时数据一致性问题的可诊断性。编译器侧refetchable如何生成查询refetchable的编译端实现在 compiler/crates/relay-transforms/src/refetchable_fragment/ 目录。从 refetchable_directive.rs 的定义可以看到该指令的完整 schema 为directive refetchable( queryName: String! directives: [String!] preferFetchable: Boolean ) on FRAGMENT_DEFINITION其中queryName用于指定自动生成查询的名字即文档示例中的CommentBodyRefetchQuery。同目录下的多个生成器对应不同 Fragment 宿主类型印证了“可重取”条件的三种情形viewer_query_generator.rsFragment 声明在Viewer类型上时生成查询query_query_generator.rsFragment 声明在Query类型上时生成查询node_query_generator.rsFragment 声明在实现了Node接口有id字段的类型上时生成查询fetchable_query_generator.rs对应fetchable类型的场景。生成的查询类型会自动导出到queryName.graphql.js文件供你像示例中那样import type {CommentBodyRefetchQuery}使用。小结以不同数据重取 Fragment 是 Relay 构建动态、可交互 UI 的基础能力。核心要点可归纳为理解语义重取 把 Fragment 放到新的查询根下、用新变量重新取数渲染Fragment 不能独立取数必须依托自动生成的查询。使用useRefetchableFragment在 Fragment 上标注refetchable(queryName: ...)用refetch(variables, options)触发重取变量只传需要改变的id可省略fetchPolicy默认store-or-network。管理加载态默认路径下确保组件上方有Suspense边界若要保留已渲染内容可用fetchQuery预取 store-only策略手动维护加载状态。理解原理编译器侧的refetchable_fragmenttransform 负责生成查询运行时侧的useRefetchableFragmentInternal负责变量合并、id自动补齐与请求编排前后端共同支撑这一能力。赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐goscan性能优化如何快速扫描大型企业网络环境goscan性能优化如何快速扫描大型企业网络环境 goscan是一款简单高效的IPv4网络扫描工具能够快速发现局域网内所有活跃设备。对于大型企业网络环境网前端开发工具Relay useFragment Hook 完全指南从 Fragment Reference 到数据订阅与 SuspenseRelay useFragment Hook 完全指南从 Fragment Reference 到数据订阅与 Suspense useFragment 是 R前端开发工具BlueBubbles Server核心功能解析从私有API到WebSocket实时通信BlueBubbles Server核心功能解析从私有API到WebSocket实时通信 BlueBubbles Server是BlueBubbles应用生态前端开发工具上一篇DiffusionDet训练完全指南从数据准备到模型优化下一篇如何快速使用霞鹜臻楷面向新手的完整字体安装指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

基于 WKWebView 的官方 iOS WebView 插件:webview_flutter_wkwebview 深度指南
基于 WKWebView 的官方 iOS WebView 插件:webview_flutter_wkwebview 深度指南

基于 WKWebView 的官方 iOS WebView 插件:webview_flutter_wkwebview 深度指南 【免费下载链接】plugins Plugins for Flutter maintained by the Flutter team 项目地址: https://gitcode.com/gh_mirrors/pl/plugins webview_flutter_wkwebview 是 Flutter … · 2026/9/21 1:36:39

在赛灵思FPGA上部署YOLOv2目标检测:从Darknet权重到硬件加速全流程解析
在赛灵思FPGA上部署YOLOv2目标检测:从Darknet权重到硬件加速全流程解析

简介:FPGA凭借可编程与高能效特性成为深度学习边缘部署的理想选择。面向AI嵌入式开发者与FPGA工程师,这份资源聚焦在赛灵思平台上完成YOLOv2实时目标检测算法的移植,覆盖模型优化、硬件逻辑设计、Vivado HLS生成IP核、系统集成与验证等关键环… · 2026/9/21 1:36:39

山特UPS电源原理图深度解析:从读图顺序到故障维修实战
山特UPS电源原理图深度解析:从读图顺序到故障维修实战

简介:山特UPS电源原理图是一份面向电源维修人员、电子工程师及电气专业学习者的电路图纸资料,旨在帮助读者理解不间断电源的完整工作链路与排障要点。图纸覆盖输入电路、直流电源部分、输出电路与控制电路,清晰标出交流转直流、直流稳压、直流… · 2026/9/21 1:35:39

线扫相机触发方案全解析:编码器选型、分辨率匹配与调试避坑
线扫相机触发方案全解析:编码器选型、分辨率匹配与调试避坑

1. 线扫相机触发到底在解决什么问题线扫相机和面阵相机最大的区别,在于它每次只拍一条线。面阵相机是“咔嚓”一下拿一整幅图,线扫相机则是像扫描仪一样,一行一行地把图像拼出来。这就带来一个绕不开的问题:相机什么时候该拍下一行… · 2026/9/21 2:24:48

STM32外设DeInit()函数详解:为何必须与Init成对使用
STM32外设DeInit()函数详解:为何必须与Init成对使用

简介:一份讲解STM32中DeInit()函数作用与必要性的PDF资料,面向嵌入式开发者和高校单片机学习者。文档围绕“为什么每个STM32模块都提供DeInit()”这一常见疑惑,先厘清Init()负责配置工作模式、波特率、中断等并启动模块,而DeInit(… · 2026/9/21 2:24:48

宏基因组功能注释实战:CAZyme与VFDB数据库搭建及DIAMOND比对全流程
宏基因组功能注释实战:CAZyme与VFDB数据库搭建及DIAMOND比对全流程

/* 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:24:48

BrowserSkill VOM视觉观察模型解析:从页面构建语义图的完整流程
BrowserSkill VOM视觉观察模型解析:从页面构建语义图的完整流程

BrowserSkill VOM视觉观察模型解析:从页面构建语义图的完整流程 【免费下载链接】BrowserSkill Let AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI agent. 项… · 2026/9/21 2:24:48

DBX CLI 数据库安全查询与 Schema 探索指南:面向 AI Agent 的命令行操作手册
DBX CLI 数据库安全查询与 Schema 探索指南:面向 AI Agent 的命令行操作手册

DBX CLI 数据库安全查询与 Schema 探索指南:面向 AI Agent 的命令行操作手册 【免费下载链接】dbx 25 MB lightweight cross-platform database client for 90 databases, including MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, SQL Server, and Dameng. B… · 2026/9/21 2:24:48

硅基集成光电子:核心材料体系与集成路线全解析
硅基集成光电子:核心材料体系与集成路线全解析

简介:《新型硅基集成微电子及光电子的材料》是一份面向微电子、光电子及相关专业学生与技术人员的PPT文档,系统讲解硅基集成微电子与光电子材料领域的关键技术。内容以摩尔定律为线索,梳理IC集成度每两年翻一番、特征尺寸持续缩小的产业规律&… · 2026/9/21 2:23:47

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

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

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

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

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

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

Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行
Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行

/* 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 0:00:18

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:18

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:18

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码