跳至主要内容
版本:v18.0.0

存储

Relay 存储可用于在 updater 函数 中以编程方式更新客户端数据。以下是 Relay 存储接口的参考。

目录

RecordSourceSelectorProxy

RecordSourceSelectorProxyupdater 函数 接收的 store 的类型。以下是 RecordSourceSelectorProxy 接口

interface RecordSourceSelectorProxy {
create(dataID: string, typeName: string): RecordProxy;
delete(dataID: string): void;
get(dataID: string): ?RecordProxy;
getRoot(): RecordProxy;
getRootField(fieldName: string): ?RecordProxy;
getPluralRootField(fieldName: string): ?Array<?RecordProxy>;
invalidateStore(): void;
}

create(dataID: string, typeName: string): RecordProxy

在存储中创建一个新记录,并提供由 GraphQL 架构定义的 dataIDtypeName。返回一个 RecordProxy,它作为对新创建的记录进行变异的接口。

示例

const record = store.create(dataID, 'Todo');

delete(dataID: string): void

从存储中删除给定 dataID 的记录。

示例

store.delete(dataID);

get(dataID: string): ?RecordProxy

从存储中检索给定 dataID 的记录。返回一个 RecordProxy,它作为对记录进行变异的接口。

示例

const record = store.get(dataID);

getRoot(): RecordProxy

返回表示 GraphQL 文档根部的 RecordProxy

示例

给定 GraphQL 文档

viewer {
id
}

用法

// Represents root query
const root = store.getRoot();

getRootField(fieldName: string): ?RecordProxy

从存储中检索给定 fieldName 的根字段,如 GraphQL 文档中定义的那样。返回一个 RecordProxy,它作为对记录进行变异的接口。

示例

给定 GraphQL 文档

viewer {
id
}

用法

const viewer = store.getRootField('viewer');

getPluralRootField(fieldName: string): ?Array<?RecordProxy>

从存储中检索表示集合的根字段,并提供由 GraphQL 文档定义的 fieldName。返回 RecordProxies 的数组。

示例

给定 GraphQL 文档

nodes(first: 10) {
# ...
}

用法

const nodes = store.getPluralRootField('nodes');

invalidateStore(): void

全局失效 Relay 存储。这将导致之前写入存储的任何数据被视为陈旧,并且在下一次查询与 environment.check() 检查时将被视为需要重新获取。

示例

store.invalidateStore();

在全局失效后,任何在重新获取之前检查的查询将被视为陈旧

environment.check(query) === 'stale'

RecordProxy

RecordProxy 充当变异记录的接口

interface RecordProxy {
copyFieldsFrom(sourceRecord: RecordProxy): void;
getDataID(): string;
getLinkedRecord(name: string, arguments?: ?Object): ?RecordProxy;
getLinkedRecords(name: string, arguments?: ?Object): ?Array<?RecordProxy>;
getOrCreateLinkedRecord(
name: string,
typeName: string,
arguments?: ?Object,
): RecordProxy;
getType(): string;
getValue(name: string, arguments?: ?Object): mixed;
setLinkedRecord(
record: RecordProxy,
name: string,
arguments?: ?Object,
): RecordProxy;
setLinkedRecords(
records: Array<?RecordProxy>,
name: string,
arguments?: ?Object,
): RecordProxy;
setValue(value: mixed, name: string, arguments?: ?Object): RecordProxy;
invalidateRecord(): void;
}

getDataID(): string

返回当前记录的 dataID

示例

const id = record.getDataID();

getType(): string

获取当前记录的类型,如 GraphQL 架构中定义的那样。

示例

const type = user.getType();  // User

getValue(name: string, arguments?: ?Object): mixed

获取当前记录中给定字段名称的字段的值。

示例

给定 GraphQL 文档

viewer {
id
name
}

用法

const name = viewer.getValue('name');

或者,如果该字段接受参数,则可以传递一个 变量 包。

示例

给定 GraphQL 文档

viewer {
id
name(arg: $arg)
}

用法

const name = viewer.getValue('name', {arg: 'value'});

getLinkedRecord(name: string, arguments?: ?Object): ?RecordProxy

根据 GraphQL 文档中定义的字段名称检索与当前记录关联的记录。返回一个 RecordProxy

示例

给定 GraphQL 文档

rootField {
viewer {
id
name
}
}

用法

const rootField = store.getRootField('rootField');
const viewer = rootField.getLinkedRecord('viewer');

或者,如果链接的记录接受参数,也可以传递一个 变量 包。

示例

给定 GraphQL 文档

rootField {
viewer(arg: $arg) {
id
}
}

用法

const rootField = store.getRootField('rootField');
const viewer = rootField.getLinkedRecord('viewer', {arg: 'value'});

getLinkedRecords(name: string, arguments?: ?Object): ?Array<?RecordProxy>

根据 GraphQL 文档中定义的字段名称检索与当前记录关联的记录集。返回 RecordProxies 的数组。

示例

给定 GraphQL 文档

rootField {
nodes {
# ...
}
}

用法

const rootField = store.getRootField('rootField');
const nodes = rootField.getLinkedRecords('nodes');

或者,如果链接的记录接受参数,也可以传递一个 变量 包。

示例

给定 GraphQL 文档

rootField {
nodes(first: $count) {
# ...
}
}

用法

const rootField = store.getRootField('rootField');
const nodes = rootField.getLinkedRecords('nodes', {count: 10});

getOrCreateLinkedRecord(name: string, typeName: string, arguments?: ?Object)

根据 GraphQL 文档中定义的字段名称检索与当前记录关联的记录。如果链接的记录不存在,它将根据类型名称创建。返回一个 RecordProxy

示例

给定 GraphQL 文档

rootField {
viewer {
id
}
}

用法

const rootField = store.getRootField('rootField');
const newViewer = rootField.getOrCreateLinkedRecord('viewer', 'User'); // Will create if it doesn't exist

或者,如果链接的记录接受参数,也可以传递一个 变量 包。

setValue(value: mixed, name: string, arguments?: ?Object): RecordProxy

通过在指定字段上设置一个新值来变异当前记录。返回变异后的记录。

给定 GraphQL 文档

viewer {
id
name
}

用法

viewer.setValue('New Name', 'name');

或者,如果该字段接受参数,则可以传递一个 变量 包。

viewer.setValue('New Name', 'name', {arg: 'value'});

copyFieldsFrom(sourceRecord: RecordProxy): void

通过从传入的记录 sourceRecord 中复制字段来变异当前记录。

示例

const record = store.get(id1);
const otherRecord = store.get(id2);
record.copyFieldsFrom(otherRecord); // Mutates `record`

setLinkedRecord(record: RecordProxy, name: string, arguments?: ?Object)

通过在给定的字段名称上设置一个新的链接记录来变异当前记录。

示例

给定 GraphQL 文档

rootField {
viewer {
id
}
}

用法

const rootField = store.getRootField('rootField');
const newViewer = store.create(/* ... */);
rootField.setLinkedRecord(newViewer, 'viewer');

或者,如果链接的记录接受参数,也可以传递一个 变量 包。

setLinkedRecords(records: Array<RecordProxy>, name: string, variables?: ?Object)

通过在给定的字段名称上设置一组新的链接记录来变异当前记录。

示例

给定 GraphQL 文档

rootField {
nodes {
# ...
}
}

用法

const rootField = store.getRootField('rootField');
const newNode = store.create(/* ... */);
const newNodes = [...rootField.getLinkedRecords('nodes'), newNode];
rootField.setLinkedRecords(newNodes, 'nodes');

或者,如果链接的记录接受参数,也可以传递一个 变量 包。

invalidateRecord(): void

使记录失效。这将导致任何引用此记录的查询被视为陈旧,直到下一次重新获取,并且在下一次这样的查询与 environment.check() 检查时将被视为需要重新获取。

示例

const record = store.get('4');
record.invalidateRecord();

在使记录失效后,任何引用失效记录的查询,并且在重新获取之前检查的查询将被视为陈旧

environment.check(query) === 'stale'

ConnectionHandler

ConnectionHandlerrelay-runtime 公开的实用程序模块,它帮助操作连接。ConnectionHandler 公开以下接口

interface ConnectionHandler {
getConnection(
record: RecordProxy,
key: string,
filters?: ?Object,
): ?RecordProxy,
createEdge(
store: RecordSourceProxy,
connection: RecordProxy,
node: RecordProxy,
edgeType: string,
): RecordProxy,
insertEdgeBefore(
connection: RecordProxy,
newEdge: RecordProxy,
cursor?: ?string,
): void,
insertEdgeAfter(
connection: RecordProxy,
newEdge: RecordProxy,
cursor?: ?string,
): void,
deleteNode(connection: RecordProxy, nodeID: string): void
}

getConnection(record: RecordProxy, key: string, filters?: ?Object)

给定记录和连接键,以及可选的过滤器集,getConnection 检索一个 RecordProxy,该记录代表一个用 @connection 指令注释的连接。

首先,让我们看一下普通的连接

fragment FriendsFragment on User {
friends(first: 10) {
edges {
node {
id
}
}
}
}

访问这样的普通连接字段与其他普通字段相同

// The `friends` connection record can be accessed with:
const user = store.get(userID);
const friends = user && user.getLinkedRecord('friends');

// Access fields on the connection:
const edges = friends && friends.getLinkedRecords('edges');

使用 usePaginationFragment 时,我们通常用 @connection 注释实际的连接字段,以告知 Relay 哪个部分需要分页

fragment FriendsFragment on User {
friends(first: 10, orderby: "firstname") @connection(
key: "FriendsFragment_friends",
) {
edges {
node {
id
}
}
}
}

对于像上面的连接,ConnectionHandler 帮助我们找到记录

import {ConnectionHandler} from 'relay-runtime';

// The `friends` connection record can be accessed with:
const user = store.get(userID);
const friends = ConnectionHandler.getConnection(
user, // parent record
'FriendsFragment_friends', // connection key
{orderby: 'firstname'} // 'filters' that is used to identify the connection
);
// Access fields on the connection:
const edges = friends.getLinkedRecords('edges');

边缘创建和插入

createEdge(store: RecordSourceProxy, connection: RecordProxy, node: RecordProxy, edgeType: string)

在给定的 store、连接、边节点和边类型的情况下,创建一个边。

insertEdgeBefore(connection: RecordProxy, newEdge: RecordProxy, cursor?: ?string)

在给定连接的情况下,将边插入连接的开头,或在指定 cursor 之前。

insertEdgeAfter(connection: RecordProxy, newEdge: RecordProxy, cursor?: ?string)

在给定连接的情况下,将边插入连接的结尾,或在指定 cursor 之后。

示例

const user = store.get(userID);
const friends = ConnectionHandler.getConnection(user, 'FriendsFragment_friends');
const newFriend = store.get(newFriendId);
const edge = ConnectionHandler.createEdge(store, friends, newFriend, 'UserEdge');

// No cursor provided, append the edge at the end.
ConnectionHandler.insertEdgeAfter(friends, edge);

// No cursor provided, insert the edge at the front:
ConnectionHandler.insertEdgeBefore(friends, edge);

deleteNode(connection: RecordProxy, nodeID: string): void

在给定连接的情况下,删除任何节点 ID 与给定 ID 相匹配的边。

示例

const user = store.get(userID);
const friends = ConnectionHandler.getConnection(user, 'FriendsFragment_friends');
ConnectionHandler.deleteNode(friends, idToDelete);