react-queryの概要を掴む
もうちょいまともなタイトルにするか、
もっと細かくページを分けて良いと思うmrsekut.icon
前提
queryの中にdataが含まれている
cacheはkey/value構造になっている
cacheはproject全体で1つのものを管理している
queryを生成する方法に、useQueryやuseInfiniteQueryなどがあるが、これらも全部込み込みでkeyはuniqueにする必要がある
用語の設定
queryとinstanceが独立であることを意識する
queryはcacheで管理され、instanceはReactのComponentの生死で管理される
だから、
「instanceは死んだが、queryは生きている」とか
「instanceは生きているが、queryは死んでいる」という状態は普通に起こりうる
例えば、cacheTime: 5minで、pagenationするときを考える
手順1. 1ページ目を表示
1ページ目のinstanceが生成され
1ページ目のqueryも生成される
手順2. 5分以内に2ページ目を表示
2ページ目のinstanceが生成がされ
2ページ目のqueryも生成される
この時、1ページ目のinstanceは死んでいるが、
1ページ目のqueryはまだ生きている
cacheTime内なので。
ただし、instanceが死んでいるため、queryはinactiveになる
ここでは、instanceが1つの場合のみを見たが、
複数のinstanceが、1つのqueryを共有していることもある
そのqueryは、どのinstanceにも使用されなくなったらinactiveになる
↑これで説明は全て。
例えば、pagenationの例を考える
cacheTime: 5minで以下の手順を踏んだ時どうなるか?
手順1. 1ページ目を表示
table:_
page1のinstance 作られた
page1のquery 作られた
手順2. 2ページ目を表示
table:_
page1のinstance unmountしたので死んだ
page1のquery instanceが死んだのinactiveに移行した。instanceが死んでからまだ5min経ってないのでcache内にいる
page2のinstance 作られた
page2のquery 作られた
手順3. 手順2から5分経過
table:_
page1のinstance 既に死んでる
page1のquery inactiveでかつ5分経過したのでcacheから削除
page2のinstance 生きている
page2のquery cache内にある
inactiveにならなければ経過時間は関係ない
cacheTime: 5minで以下の手順を踏んだ時どうなるか?
手順1. 1ページ目を表示
table:_
page1のinstance 作られた
page1のquery 作られた
手順2. そのまま5分経過
table:_
page1のinstance 生きている
page1のquery queryはinactiveでないのでcache内に存在し続ける
主語がqueryであることに注意mrsekut.icon
「cacheが」でも「dataが」でもなく、「queryが」である
staleTimeとrefetch
refetch eventが起きた時に、
新しいqueryを生成して、requestを送るか、
cacheからデータを取得するか
のいずれかが選択される
この選択の判断基準がstaleTimeである
queryが生成されてから、
staleTime以上経過していれば
queryを新しく生成する
つまり、requestを行う
staleTime経過していなければ
cacheからデータを取得する
requestは起こらない
queryは生成せず、元のものが残り続ける
この時、このqueryのstaleの経過時間はresetされるわけではない
以前のものが継続している
例えば、staleTime: 1minにした時を考える
手順1. 1ページ目を表示
refetchが起きる
queryが生成され、requestが送られる
手順2. 1min以内に、2ページ目を表示して、再び1ページ目を表示
refetchが起きる
queryは元のまま
requestは送られない
手順3. そのまま1min経過
queryがstale状態に移行する
手順4: 2ページ目を表示して、再び1ページ目を表示
refetchが起きる
queryは既に古くなっているので、新しく作り直す
requestを送る
手順1の状態とだいたい同じmrsekut.icon
staleTimeとcacheTimeの組み合わせのパターンをいくつか見てみる
defaultの時
staleTime == 0で、cacheTime == 5min
手順1. 1ページ目を表示
refetchが起きる
queryが生成され、reqが送られる
この瞬間に、もうqueryはstaleになっている
手順2. 5分以内に、2ページ目を表示し、その後1ページ目を表示
refecthが起きる
cacheからデータを取得して画面に表示
queryは古くなっているので、生成しreqを送る
server取得後、即座に画面に反映
この例では、cacheTimeはほぼ関係ないmrsekut.icon
つまり、staleTime==0の場合、cacheの有無に関わらずrefetchがあれば毎回reqが送られる
cacheTime == 0、staleTime == Infinityのとき
cacheTime: 0だと、unmountした瞬間にcacheが消える
手順1. 1ページ目を表示
table:_
page1のinstance 作られた
page1のquery 作られた。req送る
手順2. 2ページ目を表示
table:_
page1のinstance unmountしたので死んだ
page1のquery inactiveになったと同時にcacheTime経過するので、cacheから消えた
page2のinstance 作られた
page2のquery 作られた。req送る
手順3. 1ページ目を表示
table:_
page1のinstance 作られた
page1のquery 作られた。req送る
page2のinstance unmountしたので死んだ
page2のquery inactiveになったと同時にcacheTime経過するので、cacheから消えた
手順4. refocusをして、refetch
table:_
page1のinstance 生きている
page1のquery Infinityなので、再利用し続ける。reqは送らない
react-queryを使っていない時とだいたい同じ挙動になる
cacheとか気にせず、初回だけuseEffectの中でreq送ってる感じ
cacheTIme: 0にすることは基本的にない気がするmrsekut.icon
cacheTime == 0、staleTime == 0の時
request回数が最大になる設定
cacheTime == Infinity、staleTime == Infinityの時
request回数が最小になる
逆に言えばリロードしても何も更新されない
基本方針
cacheTimeは特に理由がなければdefault値で問題ない
何か問題が生じるパターンってあるかな?
例えば「6分オキに、同じページを行ったり来たりする場合」とか?
逆にcacheTime: Infinityにしたら何か問題起きるのか #?? staleが良い感じに設定されていれば、特に問題は起きなさそうな気がするけど
使用してないのに溜まっていってメモリ食うとかかmrsekut.icon
staleTimeを良い感じに調節しよう
0はコンテンツに依っては短すぎる
頻繁に更新のないものであればInfinityで良い