メインコンテンツにスキップ
バージョン: v18.0.0

クライアントスキーマ拡張

ローカルデータ更新と、ガイドツアーのクライアント専用データのセクションも参照してください。

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関数は、ローカル状態への書き込みが通常ミューテーションの外部で実行されるため、これに特に最適です。

前の例に基づいて、Usernotesリストから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');
});

このページは役に立ちましたか?

サイトをさらに改善するために、 いくつかの簡単な質問にお答えください.