🐝

【React Query】情報屋の例えでcacheTime, staleTimeを理解する

2022/07/22に公開

最近React Queryがv4になりました。

https://tanstack.com/query/v4/

オプションのcacheTime, staleTimeについて何回ググっても忘れてしまうため、
例え話で理解してみようと思います。

公式ドキュメント

https://tanstack.com/query/v4/docs/reference/useQuery

https://tanstack.com/query/v4/docs/guides/caching

cacheTime

The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used.

未使用/非活動状態のキャッシュデータがメモリ内に残る時間(ミリ秒)。クエリのキャッシュが未使用または非アクティブになった場合、そのキャッシュデータはこの時間の後にガベージコレクションされます。異なるキャッシュ時間が指定された場合、最も長いものが使用されます。

staleTime

The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on.

データが古いと判断されるまでの時間をミリ秒単位で指定する。この値は、定義されたフックにのみ適用される。

なるほど、わかったような、わからないような。

登場人物

王様

(= API)

  • Zenn王国で唯一温度計を持っている
  • 街からは離れたお城に住んでいる

国民

(= APIのデータを使用するHooksやコンポーネント)

  • Zenn王国に住んでいる
  • 気温を知りたがっている

クエリさん

(= React Query)

  • 情報屋を始めた
  • 自分用のホワイトボード(= キャッシュ)を持っている
  • 「キャッシュタイム」と名付けた砂時計(= cacheTime)を持っている
  • 「ステールタイム」と名付けた砂時計(= staleTime)を持っている

ストーリー

第1章 貴重な温度計

昔々、あるところにZenn王国がありました。

Zenn王国では温度計は大変貴重なもので、唯一王様だけが持っていました。
Zenn王国に住む国民はさまざまな場面で気温を知りたがりました。

国民は王様に気温を教えてもらいたかったのですが、
王様は街から遠く離れたお城に住んでいるため、
気温を教えてもらうには各自が王様に手紙を書くしかありませんでした。

第2章 Zenn王国の問題

王様は困っていました。

王様の元には気温を尋ねる手紙が大量に届くため、
返信の手紙を書くのも一苦労だったのです。

一方、国民もまた、困っていました。

気温を今すぐ知りたい場合でも、
王様の返信が返ってくるまで待たなければいけなかったのです。

そんな状況を見て、街に住むクエリさんはあることを思いつきました。

クエリ 「そうだ、私が気温の情報を管理する情報屋になろう!」

第3章 情報屋のクエリさん

情報屋を始めることを思いついたクエリさんは、さっそく以下のものを用意しました。

  • 自分用のホワイトボード
  • 「キャッシュタイム」と名付けた砂時計

そして、国民に対して以下のように言いました。

クエリ 「国民の皆さん、今後気温が知りたければ、私に聞いてください。」

第4章 初めてのお客さん

さっそく初めてのお客さんがきました。

国民A 「クエリさん、気温を教えてください!」

すると、クエリさんは気温を尋ねる手紙を王様に書きました。
手紙が返ってくると、クエリさんはホワイトボードに気温をメモしながら国民Aに言いました。

クエリ 「気温は22度です。」

国民Aは 「結局手紙が返ってくるまで待つんじゃん」 と思いつつ、その場をあとにしました。

クエリさんはお客さんがいなくなったので、砂時計「キャッシュタイム」 で時間を計り始めました。

第5章 2人目のお客さん

まだ砂時計「キャッシュタイム」の砂が落ちきらないうちに、2人目のお客さんが来ました。

国民B 「クエリさん、気温を教えてください!」

クエリさんは、1人目のお客さんの時とは異なり、
自分用のホワイトボードを見ながらこう答えました。

クエリ 「最新の気温は王様に聞かないと分かりませんが、先程聞いた時は22度でした。」
クエリ 「王様からの返信があり次第、最新の気温をお伝えします。」

そして、すぐに王様への手紙を送りました。

国民Bはなんとなくの気温だけでも先に知りたかったので、すぐに答えが返ってきて喜びました。

その後、クエリさんの元に王様からの手紙が返ってきたので、
ホワイトボードの気温を書き換えながら国民Bに伝えました。

クエリ 「最新の気温は24度でした。」

国民Bがその場をあとにすると、またお客さんがいなくなったので
砂時計「キャッシュタイム」も1から計り直しました。

第6章 情報屋の閑散期

そうこうしている間に夜になりました。
夜はあまりお客さんも来ません。

今まで砂時計「キャッシュタイム」の砂が落ちきる前にお客さんが来ていましたが、
初めて砂時計「キャッシュタイム」の砂が落ちきってしまいました。

クエリ 「前回のお客さんが帰ってから、かなり時間が立ってしまった。」

そう思ったクエリさんは、ホワイトボードのメモを消しました

クエリ 「ホワイトボードの気温を次のお客さんに伝えても、古い情報すぎて混乱するだろう」
クエリ 「次のお客さんが来たときは、1人目のお客さんのように王様の返信を待ってもらおう」

そう思ったのです。

第7章 情報屋の繁忙期

クエリさんの情報屋は便利なので、次第に繁盛しはじめました。

ひっきりなしにお客さんが来るので、その度に

  • お客さんにホワイトボードの気温を伝える
  • 王様に手紙で最新の気温を聞く
  • お客さんに最新の気温を伝える
  • ホワイトボードのメモを更新する

を繰り返していました。

そのうち、クエリさんはこう思うようになりました。

クエリ 「お客さんが来るたびに手紙を書いているが、王様は返信が大変じゃないだろうか?」
クエリ 「気温なんてすぐ変わるものじゃ無いんだから、ちょっと前のメモなら最新情報と言っても差し支え無いのでは?」

こう思ったクエリさんは、「キャッシュタイム」より少し小さな砂時計を持ってきて、
それに 「ステールタイム」 と名付けました。

第8章 砂時計「ステールタイム」の活躍

クエリさんは、ホワイトボードのメモを書いたり更新した際に、
合わせて砂時計「ステールタイム」で時間の計測を開始 するようにしました。

そして、次のお客さんが来た際に、砂時計「ステールタイム」の砂が落ちきっていなければメモが十分新しいと考え、
王様への手紙は書かず、ホワイトボードのメモを見て答えます。

クエリ 「最新の気温は24度でした。」

王様は手紙の返信を書く負担が減り、たいそう喜びました。

逆に、お客さんが来た際に砂時計「ステールタイム」の砂が落ちきっていれば
以前と同様にホワイトボードのメモ見てこう答えます。

クエリ 「最新の気温は王様に聞かないと分かりませんが、先程聞いた時は24度でした。」
クエリ 「王様からの返信があり次第、最新の気温をお伝えします。」

そして、すぐに王様への手紙を送り、返信が来たら
ホワイトボードの気温を書き換え、砂時計「ステールタイム」の計測を再度始めながらお客さんに伝えます。

クエリ 「最新の気温は26度でした。」

第9章 クエリさんの功績

クエリさんが情報屋を始めてからというもの、
王様は返信を書く負担が減り国民もすぐに気温が知れるようになったので、
Zenn王国はハッピーになりましたとさ。

めでたしめでたし。

まとめ

cacheTime = 砂時計「キャッシュタイム」で計る時間

砂が落ちきると、クエリさんがホワイトボードを消してしまうので、
次に来たお客さんは手紙の返信を待たないといけない。

cacheTimeの経過後にキャッシュは削除されるため、
次にデータを求められた場合はすぐにキャッシュのデータを返すことができず、
APIからのレスポンスを待つ必要がある。

staleTime = 砂時計「ステールタイム」で計る時間

砂が落ちきる前にお客さんが来ると、クエリさんは王様への手紙を書かず、
ホワイトボードのメモを最新情報としてお客さんに伝える。

staleTimeの経過前にデータを求められた場合は、
APIのリクエストを行わずにキャッシュのデータを即座に返す。

Discussion