Docblock 格式
Relay 解析器允许你在 GraphQL 模式中定义由客户端数据支持的额外类型和字段。为了实现这一点,Relay 编译器会在你的代码中查找特殊的 @RelayResolver
docblocks。这些 docblocks 定义了模式中的类型和字段,并且还告诉 Relay 在哪里可以找到实现它们的解析器函数。
有关 Relay 解析器的概述以及如何理解它们,请参阅 Relay 解析器 指南。此页面记录了 Relay 编译器查找的不同 docblock 标签,以及如何使用它们。
@RelayResolver
标签的 docblocks。其他任何 docblocks 都将被忽略。
@RelayResolver TypeName
@RelayResolver
标签后跟单个名称,在你的模式中定义了一个新的 GraphQL 类型。默认情况下,它应该后跟一个导出函数,其名称与类型名匹配。该函数应该接受一个 ID 作为其唯一参数,并返回 JavaScript 模型/对象,该对象是该类型的支持数据。请参阅 @weak
,了解定义类型支持数据的另一种方法。
- Docblock
/**
* @RelayResolver User
*/
export function User(id): UserModel {
return UserModel.getById(id);
}
/**
* @RelayResolver
*/
export function User(id): UserModel {
return UserModel.getById(id);
}
请参阅 定义类型 指南了解更多信息。
@RelayResolver TypeName.fieldName: FieldTypeName
如果 @RelayResolver
标签中的类型名后跟一个点,然后是一个字段定义,则它在类型上定义了一个新字段。.
后的部分应该遵循 GraphQL 的 模式定义语言。
字段定义应该后跟一个导出函数,其名称与字段名匹配。该函数应该接受类型解析器返回的模型/对象作为其唯一参数,并返回字段的值。
- Docblock
/**
* @RelayResolver User.name: String
*/
export function name(user: UserModel): string {
return user.name;
}
/**
* @RelayResolver
*/
export function name(user: UserModel): string {
return user.name;
}
请参阅 定义字段 指南了解更多信息。
@rootFragment
Relay 解析器还可用于对从图中其他数据派生的数据进行建模。当它们依赖的数据发生变化时,Relay 会自动重新计算这些字段。
要定义一个派生字段,请在现有字段定义上使用 @rootFragment
标签,然后在其后跟一个定义该字段依赖的数据的片段的名称。字段的解析器函数将传递一个片段键,该键可用于使用 readFragment()
读取片段数据。
- Docblock
import {readFragment} from 'relay-runtime';
/**
* @RelayResolver User.fullName: String
* @rootFragment UserFullNameFragment
*/
export function fullName(key: UserFullNameFragment$key): string {
const user = readFragment(
graphql`
fragment UserFullNameFragment on User {
firstName
lastName
}
`,
key,
);
return `${user.firstName} ${user.lastName}`;
}
import {readFragment} from 'relay-runtime';
/**
* @RelayResolver
*/
export function fullName(key: UserFullNameFragment$key): string {
const user = readFragment(
graphql`
fragment UserFullNameFragment on User {
firstName
lastName
}
`,
key,
);
return `${user.firstName} ${user.lastName}`;
}
请参阅 派生字段 了解更多信息。
@live
在对随时间变化的客户端状态进行建模时,返回单个值的解析器函数是不够的。为了适应这一点,Relay 解析器允许你定义一个返回随时间推移的值流的字段。这可以通过在字段或类型定义上添加 @live
标签来完成。
@live
解析器必须返回一个形状为 LiveStateValue
的对象,以允许 Relay 读取当前值并订阅更改。
- Docblock
import type {LiveState} from 'relay-runtime';
/**
* @RelayResolver Query.counter: Int
* @live
*/
export function counter(): LiveState<number> {
return {
read: () => store.getState().counter,
subscribe: cb => {
return store.subscribe(cb);
},
};
}
import type {LiveState} from 'relay-runtime';
/**
* @RelayResolver
*/
export function counter(): LiveState<number> {
return {
read: () => store.getState().counter,
subscribe: cb => {
return store.subscribe(cb);
},
};
}
请参阅 实时字段 指南了解更多信息。
@weak
默认情况下,Relay 解析器期望类型支持数据由解析器函数返回。但是,在某些情况下,给定类型对象可能没有标识符。在这种情况下,你可以使用上面描述的 @RelayResolver TypeName
语法,后面跟 @weak
标签来定义一个“弱”类型。
弱类型声明应该后跟一个导出类型定义,其名称与类型名匹配。
- Docblock
/**
* @RelayResolver ProfilePicture
* @weak
*/
export type ProfilePicture = {
url: string;
width: number;
height: number;
};
/**
* @RelayResolver
*/
export type ProfilePicture = {
url: string;
width: number;
height: number;
};
请参阅[弱类型](/docs/guides/relay-resolvers/defining-types/#Defining a “weak” type) 指南了解更多信息,包括如何定义到弱类型的边。
@deprecated
与 GraphQL 模式定义语言类似,Relay 解析器支持 @deprecated
标签来标记字段为已弃用。该标签后跟一个字符串,该字符串将用作弃用原因。如果使用 Relay VSCode 扩展,则已弃用的字段将在编辑器中接受特殊处理。
/**
* @RelayResolver User.name: String
* @deprecated Use `fullName` instead.
*/
export function name(user: UserModel): string {
return user.name;
}
请参阅 已弃用 指南了解更多信息。
描述
docblock 中的任何自由文本(不跟随标签的文本)都将用作类型或字段的描述。如果你使用 Relay VSCode 扩展,则该描述将在编辑器中显示。
/**
* @RelayResolver User.name: String
*
* What's in a name? That which we call a rose by any other name would smell
* just as sweet.
*/
export function name(user: UserModel): string {
return user.name;
}
请参阅 描述 指南了解更多信息。