クライアントスキーマ拡張
ローカルデータ更新と、ガイドツアーのクライアント専用データのセクションも参照してください。
Relayは、ローカルデータの読み書きに使用でき、クライアントアプリケーション内のすべてのデータに対する単一の信頼できる情報源として機能できます。
Relayコンパイラーは、スキーマのクライアントサイド拡張を完全にサポートしており、ローカルフィールドと型を定義できます。
目次:
サーバー側のスキーマの拡張
サーバー側のスキーマを拡張するには、--src
ディレクトリ内に新しい.graphql
ファイルを作成します。これを./src/clientSchema.graphql
としましょう。このファイルは、Relay設定の"schemaExtensions"
で参照されているフォルダー内にある必要があります。
このスキーマは、クライアントでクエリできるローカルデータを記述します。既存のサーバー側のスキーマを拡張するためにも使用できます。
たとえば、Note
という新しい型を作成できます。
type Note {
id: ID!
title: String
body: String
}
次に、サーバー側のスキーマ型User
を、notes
というNote
のリストで拡張します。
extend type User {
notes: [Note]
}
ローカル状態のクエリ
ローカルデータへのアクセスは、GraphQLサーバーのクエリと変わりませんが、クエリに少なくとも1つのサーバーフィールドを含める必要があります。フィールドはサーバー側のスキーマからのものでも、イントロスペクションフィールド(例:__typename
)のようなスキーマに依存しないものでもかまいません。
ここでは、useLazyLoadQueryを使用して、viewer
フィールド経由で現在のUser
を取得し、そのID、名前、およびローカルのメモリストを取得します。
// Example.js
import * as React from 'react';
import { useLazyLoadQuery, graphql } from 'react-relay';
const Example = (props) => {
const data = useLazyLoadQuery(graphql`
query ExampleQuery {
viewer {
id
name
notes {
id
title
body
}
}
}
`, {});
// ...
}
ローカル状態の変更
すべてのローカルデータは、Relay Storeに存在します。
ローカル状態の更新は、任意のupdater
関数を使用して行うことができます。
commitLocalUpdate
関数は、ローカル状態への書き込みが通常ミューテーションの外部で実行されるため、これに特に最適です。
前の例に基づいて、User
のnotes
リストからNote
を作成、更新、削除してみましょう。
作成
import {commitLocalUpdate} from 'react-relay';
let tempID = 0;
function createUserNote(environment) {
commitLocalUpdate(environment, store => {
const user = store.getRoot().getLinkedRecord('viewer');
const userNoteRecords = user.getLinkedRecords('notes') || [];
// Create a unique ID.
const dataID = `client:Note:${tempID++}`;
//Create a new note record.
const newNoteRecord = store.create(dataID, 'Note');
// Add the record to the user's list of notes.
user.setLinkedRecords([...userNoteRecords, newNoteRecord], 'notes');
});
}
このレコードは、useLazyLoadQuery
を介してExampleQuery
によってレンダリングされるため、クエリデータは自動的に保持され、ガベージコレクションされることはないことに注意してください。
ローカルデータをレンダリングするコンポーネントがなく、手動で保持する場合は、environment.retain()
を呼び出すことで保持できます。
import {createOperationDescriptor, getRequest} from 'relay-runtime';
// Create a query that references that record
const localDataQuery = graphql`
query LocalDataQuery {
viewer {
notes {
__typename
}
}
}
`;
// Create an operation descriptor for the query
const request = getRequest(localDataQuery);
const operation = createOperationDescriptor(request, {} /* variables */);
// Tell Relay to retain this operation so any data referenced by it isn't garbage collected
// In this case, all the notes linked to the `viewer` will be retained
const disposable = environment.retain(operation);
// Whenever you don't need that data anymore and it's okay for Relay to garbage collect it,
// you can dispose of the retain
disposable.dispose();
更新
import {commitLocalUpdate} from 'react-relay';
function updateUserNote(environment, dataID, body, title) {
commitLocalUpdate(environment, store => {
const note = store.get(dataID);
note.setValue(body, 'body');
note.setValue(title, 'title')
});
}
削除
import {commitLocalUpdate} from 'react-relay';
function deleteUserNote(environment, dataID) {
commitLocalUpdate(environment, store => {
const user = store.getRoot().getLinkedRecord('viewer');
const userNoteRecords = user.getLinkedRecords('notes');
// Remove the note from the list of user notes.
const newUserNoteRecords = userNoteRecords.filter(x => x.getDataID() !== dataID);
// Delete the note from the store.
store.delete(dataID);
// Set the new list of notes.
user.setLinkedRecords(newUserNoteRecords, 'notes');
});
}
ローカルの初期状態
すべての新しいクライアントサイドスキーマフィールドは、デフォルトでundefined
値になります。しかし、ローカルデータをクエリする前に初期状態を設定したい場合がよくあります。commitLocalUpdate
を介してupdater関数を使用し、ローカル状態を準備できます。
import {commitLocalUpdate} from 'react-relay';
commitLocalUpdate(environment, store => {
const user = store.getRoot().getLinkedRecord('viewer');
// initialize user notes to an empty array.
user.setLinkedRecords([], 'notes');
});
このページは役に立ちましたか?
サイトをさらに改善するために、 いくつかの簡単な質問にお答えください.