こちらはHow to update the Apollo Client’s cache after a mutationを意訳し、さらにapolloClientの仕様書での文章を読んでりかいしたことです。 英語読める方はリンク先、仕様書を見ることをお勧めします
自動的にキャッシュをアップデートさせるためには
queryすると 結果がlocalにキャッシュされる
queryの結果に対して何かのフィールドを更新、mutationすると結果がlocalにキャッシュされるが、
このときcacheされる条件は、
返り値に
-
idを含んでいる -
titleを含んでいるから(アップデートしたフィールド)
ると
どこにでもある以前までのqueryの結果を参照している値は自動的に今回のmutation結果で更新される
そのために
mutationの返り値を得るためのフィールドとqueryの結果のそれを一致させておく必要がある
そのための、
ベストプラティクスは、
全ての結果を同期させるためにfragmentでフィールドをシェアすること。
author型の中のnameフィールドが結果として更新されない場合idが存在しないことが原因のケースがある
mutaton後に自動的にキャッシュが更新されないケース
- 作成(create)
- 削除(delete)
- フィルター
でmutationしたケース
この場合手動で更新する。 2つの方法がある
- ブラウザをリフレッシュ
- update関数でローカルキャッシュにアクセスして更新
3つめとして、refetchQueryがあるが、ネットワークを利用することになる
mutation後にrenderProps内で実行できるupdate関数の引数には
1つめに現在のcacheデータ、2つめにoptimisticレスポンスか実際のサーバーからのレスポンスが渡ってくる
optimasticレスポンスというのはオプションで設定できるもので、
サーバーからのmutationの返値をまたずに、事前にこちらが予測できうる返値を提供
キャッシュを更新することが可能です。
そのためユーザーは速く感じることができます
この場合update関数は2回呼ばれ、
2回目は実際のサーバーからの応答が返ってきます
refetchQueries・・・サーバーにqueryの再取得し正規化、キャッシュを新しいものにする
-
refetch={[string]}ならoperationネームを渡す
-
オブジェクトなら {query: “operationname”}
awaitRefetchQueries・・・デフォルトではmutationが終わる前にrefetchしないケースもある(defaultはfalse)
updateQueriesは・・・廃止される予定。updateを使うこと
update関数は当然local cacheを更新するのでrefetchQueriesより速く感じる
もしまだqueryがfetchし終わっていないなら
proxy.readQueryはErrorを
投げ、アプリケーションはクラッシュします
queryが安全に扱えるようになった場合を保証するために
try/chachを使いましょう
try/cactch、それ以外の方法はqueryがすでにcache内にあることを確認する方法があります
readQeuryもwriteQeryもエラーをなげます
書き込み操作時の間にキャッシュから読み込むとfieldがないためにエラーをなげることがあります
損失しているfieldは__typenameになるでしょう
記事を扱うqueryがあるとして
全ての記事を叩くquery、
さらに公開未公開で叩いたqueryはそれぞれでキャッシュがつくられて
posts
posts({variables: {open: true}})
posts({variables: {open: false}})
3つたたくと
ちがうエンティティのキャッシュ3つできる
それぞれベてをreadQuery, writeQueryで更新する必要がある
また同じquery operation nameでリクエストした際でもvariablseの順番が違うと
{variables: {width: “100”, height:”50”}}
{variables: {height: “50”, width:”100"}}
別でキャッシュされる
posts({“width”: 100, “height”: 50})
posts({“height”: 50, “height”: 100})
順番はおなじでも値が違うvariablseを叩いても
{variables: {width: “100”, height:”50”}}
{variables: {height: “50”, width:”100”}}
{variables: {height: “50”, width:”600”}}
追加でつくられる
posts({“width”: 100, “height”: 50})
posts({“height”: 50, “height”: 100})
posts({“height”: 50, “height”: 600})
もし
{variablse: pops.some}
として
動的に値が渡ってきたものをリクエストしたら、
(props.someが {width: null, height: null}
としてprops.someが渡ってきたら)
cacheは
operationname ({"width": null, "height": null})
になります
全く渡していなかったら
`gql`${SOME}`
posts({})
になる
see: How to update the Apollo Client’s cache after a mutation
