useRefetchableFragment
useRefetchableFragment
当您想要使用不同的数据获取和重新渲染片段时,可以使用 useRefetchableFragment
import type {CommentBody_comment$key} from 'CommentBody_comment.graphql';
const React = require('React');
const {graphql, useRefetchableFragment} = require('react-relay');
type Props = {
comment: CommentBody_comment$key,
};
function CommentBody(props: Props) {
const [data, refetch] = useRefetchableFragment(
graphql`
fragment CommentBody_comment on Comment
@refetchable(queryName: "CommentBodyRefetchQuery") {
body(lang: $lang) {
text
}
}
`,
props.comment,
);
return (
<>
<p>{data.body?.text}</p>
<Button
onClick={() => {
refetch({lang: 'SPANISH'}, {fetchPolicy: 'store-or-network'})
}}
>
Translate Comment
</Button>
</>
);
}
module.exports = CommentBody;
参数
fragment
: 使用graphql
模板文字指定的 GraphQL 片段。该片段必须具有@refetchable
指令,否则使用它将抛出错误。@refetchable
指令只能添加到“可重新获取”的片段中,即,在声明在Viewer
或Query
类型上,或在实现Node
的类型上的片段中(即,具有id
且可以通过其id
字段进行查询的类型。有关更多详细信息,请参阅 graphql 服务器规范部分)。- 请注意,您无需手动指定重新获取查询。
@refetchable
指令将使用指定的queryName
自动生成查询。这也将为查询生成 Flow 类型,可从生成的以下文件导入:<queryName>.graphql.js
。
- 请注意,您无需手动指定重新获取查询。
fragmentReference
: 片段引用 是 Relay 用来从存储中读取片段数据的透明 Relay 对象;更具体地说,它包含有关应从哪个特定对象实例读取数据的信息。- 片段引用的类型可以从生成的 Flow 类型中导入,从
<fragment_name>.graphql.js
文件导入,并可用于声明您的Props
的类型。片段引用类型的名称将为:<fragment_name>$key
。我们使用我们的 lint 规则 来强制执行片段引用道具的类型是否正确声明。
- 片段引用的类型可以从生成的 Flow 类型中导入,从
返回值
包含以下值的元组
- [0]
data
: 包含已从 Relay 存储中读取的数据的对象;该对象与指定片段的形状匹配。- 数据对应的 Flow 类型也将与该形状匹配,并将包含从 GraphQL 架构派生的类型。
- [1]
refetch
: 用于使用潜在的新变量集重新获取片段的函数。- 参数
variables
: 包含要用于获取@refetchable
查询的新变量值集的对象。- 这些变量需要与片段内引用的 GraphQL 变量匹配。
- 如果传递给
useRefetchableFragment
的片段键是可选的,则必须传递所有非可选变量,包括潜在的对象 ID,因为 Relay 可能没有要重用的现有变量。 - 如果片段键是非可选的,则只需要指定要更改以进行重新获取请求的变量;任何未从该输入中省略的片段引用的变量将回退到使用父查询中指定的值。例如,要使用与最初获取时完全相同的变量重新获取片段,可以调用
refetch({})
。 - 同样,如果片段键是非可选的,则传递
$id
变量的id
值是可选的,除非片段想要使用不同的id
重新获取。在重新获取非空@refetchable
片段时,Relay 已经知道渲染对象的 id。
options
: [可选] 选项对象fetchPolicy
: 确定是否应使用缓存的数据,以及何时根据可用的缓存数据发送网络请求。有关完整规范,请参阅 获取策略 部分。onComplete
: 重新获取请求完成时(包括任何增量数据有效负载)将被调用的函数。
- 返回值
disposable
: 包含dispose
函数的对象。调用disposable.dispose()
将取消重新获取请求。
- 行为
- 使用一组新的变量调用
refetch
将使用新提供的变量再次获取片段。请注意,您需要提供的变量只是片段内引用的变量。在此示例中,这意味着通过传递一个新的值给lang
变量,来获取当前渲染的评论的翻译后的主体。 - 调用
refetch
将重新渲染您的组件,并可能导致其暂停,具体取决于指定的fetchPolicy
以及缓存的数据是否可用或是否需要发送和等待网络请求。如果重新获取导致组件暂停,则需要确保有一个Suspense
边界包裹着此组件。 - 有关 Suspense 的更多详细信息,请参阅我们的 使用 Suspense 的加载状态 指南。
- 使用一组新的变量调用
- 参数
行为
- 组件会自动订阅到片段数据更新:如果该特定
User
的数据在应用程序中的任何位置更新(例如,通过获取新数据或修改现有数据),该组件将自动使用最新更新的数据重新渲染。 - 如果缺少特定片段的任何数据,并且该数据当前正在由父查询获取,则组件将暂停。
- 有关 Suspense 的更多详细信息,请参阅我们的 使用 Suspense 的加载状态 指南。
与 RefetchContainer
的区别
- 在这个 api 中,不再需要指定重新获取查询,因为 Relay 将通过使用
@refetchable
片段自动生成它。 - 重新获取不再区分
refetchVariables
和renderVariables
,它们之前是定义模糊的概念。重新获取将始终正确地使用您提供的变量来重新获取和渲染片段(在输入中省略的任何变量将回退到使用来自父查询的原始值)。 - 重新获取将明确地更新组件,这在从
RefetchContainer
调用重新获取时并不总是正确的(它将取决于您在重新获取查询中查询的内容以及您的片段是否在正确的对象类型上定义)。
此页面是否有用?
通过 回答几个快速问题.