💪

【Apollo Client】readFragmentとwriteFragmentを使ってキャッシュを操作する。

2023/02/05に公開

readFragmentとwriteFragmentを使用することで、クエリ全体を構成することなく、キャッシュオブジェクトのフィールドにアクセスすることができます。

fragment = フラグメント は 「かけら」や「断片」といった意味を持ちます。
つまりreadFragmentは「断片を読む」、writeFragmentは「断片を書き込む」と和訳でき、
Apolloで使用されるということを踏まえて噛み砕くと、

readFragmentはキャッシュされたオブジェクト(キャッシュ)の一部分を読むことができるメソッドで、

writeFragmentはキャッシュされたオブジェクト(キャッシュ)に対して、部分的に書き込みができるメソッド

と解釈することができます。

実際にreadFragmentとwriteFragmentを使用してみたいと思います。

readFragment

https://www.apollographql.com/docs/react/api/cache/InMemoryCache#readfragment

全体のコード

const [fetchYutaWatanabe] = useLazyQuery(FETCH_PLAYER, {
    variables: {
      id: "1",
    },
  });
  const onClick = async () => {
    const {
      data: { fetchPlayerById },
      client,
    } = await fetchYutaWatanabe();

    //キャッシュidを取得
    const id = client.cache.identify(fetchPlayerById);

    //フラグメント文
    const fragment = gql`
      fragment YutawatanabeTeam on Player {
        id
        team
      }
    `;

    const team = client.readFragment({
      id,
      fragment,
    });

    console.log(team);
  };

ポイント

  const [fetchYutaWatanabe] = useLazyQuery(FETCH_PLAYER, {
    variables: {
      id: "1",
    },
  });

useQueryではなく、useLazyQueryを使用することで任意のタイミングでクエリを叩くことができます。
今回はボタンが押されたタイミングでクエリ(fetchYutaWatanabe)を発火させます。

const {
      data: { fetchPlayerById },
      client,
    } = await fetchYutaWatanabe();

上記クエリが実行され、fetchPlayerByIdにクエリの実行結果が、そしてclientにはクエリを実行したApolloインスタンスが代入されます。このApolloインスタンスを利用してキャッシュの操作を行うことができます。

またこのクエリを叩いて、成功した時点で以下のようなキャッシュが保存されています。

上記キャッシュからidとteam情報だけ抜き出したいので、readFragmentを使用します。

 const id = client.cache.identify(fetchPlayerById);

上記のようにしてキャッシュidを取得します。

 const fragment = gql`
      fragment YutawatanabeTeam on Player {
        id
        team
      }
    `;

fragment キーワード on キャッシュされたオブジェクト名 {
取得したいフィールド
}
のようにして、読みたい1部のフィールドを指定します。

    const team = client.readFragment({
      id,
      fragment,
    });

    console.log(team);

そして先ほど用意したidとfragmentをreadFragmentのオプションに指定して、
以下のようにキャッシュされたオブジェクトから、指定したフィールドの値を持つオブジェクトを取得することができました。

writeFragment

https://www.apollographql.com/docs/react/caching/cache-interaction/#writefragment

//キャッシュidを取得
    const id = client.cache.identify(fetchPlayerById);

    //フラグメント文
    const fragment = gql`
      fragment YutawatanabeTeam on Player {
        team
      }
    `;

    //書き込むdata
    const data = {
      team: "Brooklyn",
    };

    client.writeFragment({
      id,
      data,
      fragment,
    });

readFragmentと似ています。
書き換えるフィールドをfragment文で指定して、dataプロパティに更新後のデータを指定し、
writeFragmentを実行して、キャッシュを更新します。

実際にクエリを叩いた後、Player:1のteamフィールドにはTorontoというデータがキャッシュされているはずですが、
writeFragmentによって、teamフィールドはBrooklynというデータに書きかわります。

Discussion