Apolloキャッシュ:正規化と更新
Apolloの正規化されたInMemoryCacheを理解し、再取得せずにMutation後のキャッシュデータを更新します
「Apolloキャッシュ:正規化と更新」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
InMemoryCacheによるデータの正規化
InMemoryCacheは、__typenameとidで構成されるキャッシュキー(User:1、Post:42)ごとに各オブジェクトを保存します。クエリがid "1" のUserを返すと、異なるクエリに何度含まれていても、このキーの下に一度だけ保存されます。
以降のクエリで同じUser:1を取得すると、単一のキャッシュエントリから読み取られるため、すべてのコンポーネントで同じデータが表示されます。
クエリ間の自動更新
ミューテーションが更新済みのUser:1オブジェクトを返すと、ApolloはそれをUser:1のキャッシュエントリに書き込みます。User:1を含むアクティブなクエリはすべて、追加のコードなしでUIに更新されたフィールドを自動的に反映します。
この自動的な伝播が、ドキュメント(クエリキー方式)キャッシュに対する正規化キャッシュの主な利点です。
cache.readQuery
クエリの現在のキャッシュ結果を読み取ります。cache.readQuery({ query: GET_USERS })は、useQueryが返した場合と同じようにデータオブジェクトを返します。クエリがキャッシュに存在しない場合はnullを返します。
変更する前の現在のリストを読み取るには、ミューテーションのupdate関数内でreadQueryを使用します。
cache.writeQuery
cache.writeQuery({ query: GET_USERS, data: { users: updatedUsers } })はキャッシュに直接書き込み、GET_USERSを読み取るすべてのコンポーネントで再レンダリングを発生させます。ネットワークリクエストは実行されません。
readQueryとwriteQueryを組み合わせると、イミュータブルなキャッシュ更新を実装できます。読み取り、新しい配列の生成、書き戻しという流れです。
cache.modifyによる直接的なエンティティ更新
cache.modify({ id: cache.identify(user), fields: { name: () => 'New Name' } })は、特定のキャッシュエンティティのフィールドを直接変更します。エンティティのキャッシュIDがわかっている場合は、先にクエリを読み取る必要はありません。
fieldsオブジェクトでは、フィールド名をモディファイア関数に対応付けます。モディファイア関数は現在の値を受け取り、新しい値を返します。
ミューテーション後のキャッシュ更新
useMutationにupdate関数を渡します。useMutation(ADD_POST, { update(cache, { data: { addPost } }) { cache.modify({ id: cache.identify(user), fields: { posts: existingPosts => [...existingPosts, addPost] } }); } })。
これにより、新しい投稿がユーザーのキャッシュ済み投稿配列に追加され、ユーザーの投稿一覧を表示するすべてのコンポーネントが更新されます。
cache.evict:キャッシュエントリの削除
cache.evict({ id: 'User:1' })は、User:1のエントリをキャッシュから削除します。User:1を含むアクティブなクエリは、該当エンティティが結果からなくなった状態で再レンダリングされます。
エントリを削除した後は、cache.gc()を呼び出して、ルートクエリから到達できなくなったオブジェクトを削除します。これにより、長時間稼働するアプリケーションでのメモリリークを防げます。
ガベージコレクション
cache.gc()は、すべてのアクティブなクエリを起点にキャッシュグラフをたどり、到達できなくなったエンティティを削除します。定期的に呼び出したり、多数のエンティティを削除する一括ミューテーションの後に呼び出したりしても安全です。
アクティブなuseQueryフックから参照されているエンティティはガベージコレクションの対象になりません。対象になるのは、どのクエリ結果にも含まれなくなった孤立エンティティだけです。
フィールドポリシーによるキャッシュリダイレクト
一覧クエリの一部としてすでにキャッシュされている単一エンティティ(idによるGET_USER)をクエリする場合、Apolloはtype policyのkeyArgsとread関数によるフィールドポリシーを使って、ネットワークへの往復なしにキャッシュから読み取れます。
read関数はキャッシュ参照を返します。return toReference({ __typename: 'User', id: args.id })と記述することで、既存のUser:idキャッシュエントリから読み取るようApolloに指示します。
標準以外のIDに対するカスタムkeyFields
エンティティで一意なキーとしてid以外のフィールド(例:slugやuuid)を使用する場合は、type policyで設定します。new InMemoryCache({ typePolicies: { Post: { keyFields: ['slug'] } } })。
Apolloはidフィールドを必須にせず、代わりにPost:my-post-slugをキャッシュキーとして使用するため、標準以外のスキーマでも正規化を維持できます。
refetchQueriesとupdate関数の比較
useMutationのオプションでrefetchQueries: [{ query: GET_USERS }]を指定すると、ミューテーションの完了後にネットワークから再取得します。より簡単ですが、必ずネットワークリクエストが発生します。
update関数はキャッシュをローカルで変更するため、ネットワークへの往復を避けられます。キャッシュ更新のロジックが複雑で記述しにくい場合や、サーバーで計算されるフィールドのためにローカルでのキャッシュ更新が信頼できない場合は、refetchQueriesを使用します。
InMemoryCacheの正規化キー
InMemoryCacheがエンティティの保存に使用するデフォルトのキャッシュキーの形式は何ですか。
レッスンのまとめ
InMemoryCacheは__typename+idによってエンティティを正規化し、クエリ間の自動更新を可能にします。cache.readQuery、cache.writeQuery、cache.modifyでキャッシュを読み書きします。cache.evictでエンティティを削除した後、cache.gcを実行して不要なエンティティを回収します。id以外を主キーにする場合は、typePoliciesでカスタムキーのフィールドを設定します。
ローカルキャッシュを効率よく更新するにはミューテーションのupdate関数を使用します。サーバーで計算されるフィールドによってローカル更新が信頼できない場合は、refetchQueriesを使用します。
よくある質問
「Apolloキャッシュ:正規化と更新」レッスンは無料ですか?
はい。「Apolloキャッシュ:正規化と更新」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「Apolloキャッシュ:正規化と更新」で何を学びますか?
Apolloの正規化されたInMemoryCacheを理解し、再取得せずにMutation後のキャッシュデータを更新します ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Apolloキャッシュ:正規化と更新」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- React開発者のためのGraphQL基礎
- ReactでのApollo Clientセットアップ
- useQueryとuseMutationフック
- Apolloキャッシュ:正規化と更新