GraphQL 指令
Relay 使用指令向 GraphQL 文档添加额外的信息,这些信息被 Relay 编译器 用于生成相应的运行时工件。这些指令只出现在您的应用程序代码中,并从发送到您的 GraphQL 服务器的请求中删除。
**注意:** Relay 编译器会维护服务器支持的任何指令(例如 `@include` 或 `@skip`),因此它们会保留在发送到 GraphQL 服务器的请求中,并且不会更改生成的运行时工件。@arguments
@arguments
是一个指令,用于将参数传递给使用 @argumentDefinitions
定义的片段。例如
query TodoListQuery($userID: ID) {
...TodoList_list @arguments(count: $count, userID: $userID) # Pass arguments here
}
@argumentDefinitions
@argumentDefinitions
是一个指令,用于指定片段接受的参数。例如
fragment TodoList_list on TodoList
@argumentDefinitions(
count: {type: "Int", defaultValue: 10} # Optional argument
userID: {type: "ID"} # Required argument
) {
title
todoItems(userID: $userID, first: $count) {
# Use fragment arguments here as variables
...TodoItem_item
}
}
提供的变量
提供的变量是一种特殊的片段变量,其值在运行时由指定的提供程序函数提供。这简化了将设备属性、用户实验标志和其他运行时常量提供给 graphql 片段。
要添加提供的变量
- 在
@argumentDefinitions
中添加一个带有provider: "[JSModule].relayprovider"
的参数 - 确保
[JSModule].relayprovider.js
存在并导出一个get()
函数get
应该在给定运行的每次调用中返回相同的值。
fragment TodoItem_item on TodoList
@argumentDefinitions(
include_timestamp: {
type: "Boolean!"
provider: "Todo_ShouldIncludeTimestamp.relayprovider"
}
) {
timestamp @include(if: $include_timestamp)
text
}
// Todo_ShouldIncludeTimestamp.relayprovider.js
export default {
get(): boolean {
// must always return true or false for a given run
return check('todo_should_include_timestamp');
},
};
笔记
- 尽管片段在
argumentDefinitions
中声明提供的变量,但它们的父级不能通过@arguments
传递提供的变量。 - 参数定义不能同时指定提供程序和默认值。
- 不稳定/可能发生变化
- Relay 将提供的变量转换为操作根变量,并将它们重命名为
__relay_internal__pv__[JsModule]
。- 仅在您调试使用提供的变量的查询时才相关。
- Relay 将提供的变量转换为操作根变量,并将它们重命名为
@catch
@catch
是一个指令,您可以在 Relay 查询中的字段中添加它,以声明如何在运行时处理字段级异常。
另请参阅 @catch 指南。
@connection(key: String!, filters: [String])
使用 usePaginationFragment
,Relay 期望连接字段用 @connection
指令进行注释。有关更详细的信息和示例,请查看 关于 usePaginationFragment
的文档。
@refetchable(queryName: String!, directives: [String], preferFetchable: Boolean)
使用 useRefetchableFragment
和 usePaginationFragment
,Relay 期望 @refetchable
指令。@refetchable
指令只能添加到“可重取”的片段,即在 Viewer
或 Query
类型上声明的片段,或者在实现 Node
的类型上(即具有 id 的类型)。@refetchable
指令将自动生成一个具有指定 queryName
的查询。这还将为查询生成 Flow 类型,可从生成的 文件中导入:<queryName>.graphql.js
。有关更详细的信息和示例,请查看 useRefetchableFragment
或 usePaginationFragment
的文档。
可选地,您可以传入一个指令列表以添加到自动生成的查询中。例如,这可用于添加用于 测试 的 @relay_test_operation
指令
[可选] preferFetchable: Boolean
此参数告诉 Relay 编译器优先为实现 Node
接口的类型生成 fetch_MyType(): MyType
查询。这对已采用 @strong
和 @fetchable
服务器注释的类型的模式很有用。您可以直接获取具体对象,而无需将 Node
接口细化为特定类型。
graphql`
fragment FriendsListComponent_user on User
@refetchable(
queryName: "FriendsListFetchQuery"
directives: ["@relay_test_operation"]
) {
...
}
`;
@relay(plural: Boolean)
在为与片段容器一起使用定义片段时,您可以使用 @relay(plural: true)
指令来指示容器期望该片段的道具是项目列表而不是单个项目。扩展 @relay(plural: true)
片段的查询或父级应在复数字段(即由 GraphQL 列表 支持的字段)中执行此操作。例如
// Plural fragment definition
graphql`
fragment TodoItems_items on TodoItem @relay(plural: true) {
id
text
}
`;
// Plural fragment usage: note the parent type is a list of items (`TodoItem[]`)
fragment TodoApp_app on App {
items {
// parent type is a list here
...TodoItem_items
}
}
@required
@required
是一个指令,您可以在 Relay 查询中的字段中添加它,以声明如何在运行时处理空值。
另请参阅 @required 指南。
@throwOnFieldError
@throwOnFieldError
是一个指令,您可以在 Relay 查询和片段中添加它,以使 Relay 在读取查询或片段时遇到任何字段错误时抛出异常。添加该指令将允许 Relay 为模式中标记为 @semanticNonNull
的任何字段生成非空类型。
另请参阅 @throwOnFieldError 指南。
详细了解 Relay 对 语义非空性 的实验性支持。
@semanticNonNull
@semanticNonNull
指令可以添加到模式中的字段,以指示该字段在语义意义上是非空的,但客户端仍应准备好处理错误。
详细了解 Relay 对 语义非空性 的实验性支持。
@alias
@alias
是一种指令,允许您为片段扩展或内联片段提供别名,类似于字段别名。当您想有条件地包含片段并检查它是否被获取,或者以其他方式将数据分组在一起时,这很有用。
对于片段扩展,别名将默认为片段名称。对于内联片段,别名将默认为类型名称。如果您希望提供自己的名称,或者您有一个没有类型条件的内联片段,您可以使用 as
参数指定别名。
fragment MyFragment on User {
... on User @alias(as: "myGreatAlias") {
name
}
}
另请参阅 @alias 指南。
@inline
Relay 公开的钩子 API 允许您仅在渲染阶段从存储区读取数据。为了从渲染阶段之外(或从 React 之外)读取数据,Relay 公开了 @inline
指令。使用 readInlineData
可以读取用 @inline
注释的片段中的数据。
在下面的示例中,函数 processItemData
从 React 组件中调用。它需要一个具有特定字段集的 item 对象。所有使用此函数的 React 组件都应该扩展 processItemData_item
片段,以确保为该函数加载了所有正确 item 数据。
import {graphql, readInlineData} from 'react-relay';
// non-React function called from React
function processItemData(itemRef) {
const item = readInlineData(
graphql`
fragment processItemData_item on Item @inline {
title
price
creator {
name
}
}
`,
itemRef,
);
sendToThirdPartyApi({
title: item.title,
price: item.price,
creatorName: item.creator.name,
});
}
export default function MyComponent({item}) {
function handleClick() {
processItemData(item);
}
const data = useFragment(
graphql`
fragment MyComponent_item on Item {
...processItemData_item
title
}
`,
item,
);
return <button onClick={handleClick}>Process {item.title}</button>;
}
@relay(mask: Boolean)
不建议使用 @relay(mask: false)
。请改为考虑使用 @inline
片段。
@relay(mask: false)
可用于防止数据屏蔽;当包含片段并用 @relay(mask: false)
注释它时,其数据将直接提供给父级,而不是被屏蔽以用于不同的容器。
应用于片段定义,@relay(mask: false)
会更改生成的 Flow 类型,使其在使用相同的指令包含片段时更容易使用。Flow 类型将不再是精确对象,也不再包含内部标记字段。
这可能有助于在处理单个组件中的嵌套或递归数据时减少冗余片段。
请记住,在多个容器之间共享单个片段通常被认为是一种反模式。滥用此指令会导致应用程序过度获取。
在下面的示例中,user
道具将在任何包含 ...Component_internUser
的地方包含 id
和 name
字段的数据,而不是 Relay 的正常行为,即屏蔽这些字段
graphql`
fragment Component_internUser on InternUser @relay(mask: false) {
id
name
}
`;
@waterfall
使用 Relay 解析器,可以在图中创建指向服务器类型的客户端定义的边。在读取这些边字段时,Relay 被迫延迟获取边的服务器数据。这将迫使 Relay 向服务器发出第二个请求以获取边的数据。
为了在编辑器和代码审查期间突出显示这种权衡,Relay 编译器期望所有读取这些字段的操作都用 @waterfall
进行注释。
fragment EditPost on DraftPost {
author @waterfall {
name
}
}
有关更多信息,请参阅 Relay 解析器指南的 返回类型 部分。
此页面是否有用?
通过以下方式帮助我们使网站更棒 回答几个快速问题.