こちらは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