TanStack QueryのisPendingisLoadingisFetchingについて、違いはなんとなく理解しているものの、なぜこんなに似た状態が用意されているのか気になったので調べてみました。

isPendingisLoadingisFetchingの違い

プロパティ

trueになるタイミング

主な用途

isPending

データがまだ利用できない

初回ローディングの判定

isLoading

初回データ取得中

初回通信中の判定

isFetching

通信中

バックグラウンド更新中の表示

一言でまとめると

  • isPending: データがまだ利用できない状態
  • isLoading: 初回データ取得中
  • isFetching: 通信中(初回取得・再取得の両方を含む)

なぜこんなに似た状態があるのか?

これらは、TanStack Queryが内部で管理しているstatusfetchStatusという2つの状態から導き出されています。

statusとは

statusは、クエリが保持しているデータの状態を表します。

取り得る値は次の3つです。

status

説明

pending

データがまだ利用できない

success

データの取得に成功した

error

データの取得に失敗した

status通信中かどうかを表しているわけではない。

「データが利用できる状態なのか」「取得に失敗した状態なのか」といった、データそのものの状態を表しています。

fetchStatusとは

クエリの通信状態を表します。

fetchStatus

説明

fetching

通信中

paused

通信が一時停止している

idle

通信していない

statusとの違いは、データではなく通信に着目していることです。

つまり、

  • statusデータの状態
  • fetchStatus通信の状態

という役割で分かれています。

isPendingisLoadingisFetchingはどのように導き出されるのか

プロパティ

判定

isPending

status === 'pending'

isFetching

fetchStatus === 'fetching'

isLoading

isPending && isFetching

isPendingisFetchingは、それぞれstatusfetchStatusをそのまま分かりやすくしたものです。

isLoadingだけは少し特殊で、「データがまだ利用できず、かつ通信中である」場合にのみtrueになります。

そのため、例えばオフラインなどで通信が一時停止している場合は、

  • status = 'pending'
  • fetchStatus = 'paused'

となり、

  • isPending = true
  • isFetching = false
  • isLoading = false

となる。

つまり、isLoadingは「初回ローディング中」を表現するための、より限定的な状態であることが分かります。

まとめ

isPendingisLoadingisFetchingは、それぞれ独立した状態ではなく、statusfetchStatusから導き出される派生プロパティです。

  • statusデータの状態
  • fetchStatus通信の状態
  • isPendingstatusを分かりやすくしたもの
  • isFetchingfetchStatusを分かりやすくしたもの
  • isLoadingは「データがまだ利用できず、かつ通信中」であることを表す

このように、まずstatusfetchStatusの役割を理解すると、isPendingisLoadingisFetchingの違いも自然と理解しやすくなります。