クライアントスキーマ拡張
ローカルデータ更新と、ガイドツアーのクライアント専用データのセクションも参照してください。
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');
});
このページは役に立ちましたか?
サイトをさらに改善するために、 いくつかの簡単な質問にお答えください.