14
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ウェブクルーAdvent Calendar 2022

Day 5

TanStack Query(旧React Query)について整理してみた

Last updated at Posted at 2022-12-04

この記事は ウェブクルー Advent Calendar 2022 5日目の記事です。
昨日は @wc-nakagomi さんの「 【タイポ好きデザイナー厳選】 本当に使える Adobe Fonts 18選!」でした。

はじめに

まずこちらのライブラリはSWRみたいな挙動(APIなどから取得したデータをクライアント側でキャッシュをしレンタリング最適化できる仕組み)を簡単に実現できるライブラリです。
TanStack Queryというのはv3まではReact Queryと呼ばれておりました。
v4以降でTanStack Queryというものに変更されました。挙動としてはほぼ変わらずTanStack Query(旧React Query)という解釈ですが、
TanStack QueryになってからはReact以外のVueやSolidのQueryも統合されたました。
TanStack Queryの大まかな機能としては下記かな?と思っております。

  1. APIからデータを取得する際の記述量が少なく楽
  2. APIから取得してデータをキャッシュに保存し、再フェッチせずともデータを参照できる

上記の中でも2のキャッシュを残して再フェッチせず済むというのが大きなメリットかなと思われます。
今回はそのTanStack Query(Reactで使用の場合)について少しまとめていきたいと思います。

初期設定

手順としては簡単で下記2つの手順で実装できます。

1.下記コマンドでインストール
お察しの通りVueなどで使用したい場合は`@tanstack/vue-query`に変更していただければと。

npm i @tanstack/react-query

2.次に_app.jsでAPIのキャッシュデータを全ページで使えるよう設定していきます

_app.js
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

function App() {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
       //略
       <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  );
}

プログラム上にさらっと記載しましたReactQueryDevtoolsタグですが、これもTanstack Queryの機能の一つでデベロップツールとなります。
それによりどのようなデータがキャッシュされているか、データがどの状態(ここに関しては後程記載して行きます)なのかを目視で確認できます。(画像を参照)

スクリーンショット 2022-11-18 9.19.30.png

こちらはデフォルトでprocess.env.NODE_ENV === 'development'という記述が@tanstack/react-queryに入っているため開発環境でのみ表示される仕様になっております。
補足でオプションに設定されているinitialIsOpen={false}を追加する事により初期表示で下記画像のアイコンだけになり、アイコンをクリックすると上記のようにデベロップツールが開かれるというようなものです。
スクリーンショット 2022-11-18 9.19.44.png

以上でTanStack Queryを使う準備が整いました。

記述の説明

index.js

import { useQuery } from 'react-query';

const { data, isLoading, isError, error, status } = useQuery(
  'クエリキー',
  'クエリ関数',
  {
    cacheTime: 1000,
  }
);

よく使うパターンはざっと上記のようになるかなと思われます。
ここに関しては ドキュメントを読んだ方がわかりやすいかなと?思われますが、ざっと説明します。

戻り値について

下記表のものをよく使うかなと思われます。
isLoadingに関しては、if文でクエリの試行が完了するまでデータ表示に関わる部分は表示せずに<div>Loading....</div>を表示させておくケースをよく見ますね。

example.js
if(isLoading) return <div>Loading...</div>
戻り値 説明
data 正常にクエリの試行できた際に返り値が入る部分。初期値はundefined
isLoading クエリの試行がまだ完了していない場合にtrueを返し、完了した場合はfalseを返す
isError クエリの試行でエラーが発生した場合にtrueを返し、エラー発生していない場合はfalseを返す
error クエリの試行でエラーが発生した場合いにエラーコードがオブジェクト形式で返される。
status 現状クエリの試行がどの状態かを示したもの 例)loading,error,success

クエリキー

dataの値がある場合にそれを引っ張ってくるためのkeyみたいなものです。
下記のように配列に定数or変数を入れ設定できます。例1ですとtestという名のクエリキーを設定しています。
また、ドキュメントを見た感じキーが変更される度に再フェッチするような感じなため
例2のようにするとnum変数が変更される度に再フェッチしてくれるみたいです。そのためこの機能は動的ページでidが変更される度にフェッチされるページで使用するケースが多いのかな?と感じました。

example.js
//例1
const {data} = useQuery(['test'] ...);

//例2
const [num setNume] = useState(0)
const {data} = useQuery(['test',num] ...);

クエリ関数

これは非同期でデータを取得する関数をここに設定します。
下記で記載していますqueryFnなどをよく見ます。

example.js
const queryFn: async () => {
   const response = await fetch('/todos/' + todoId)
   if (!response.ok) {
     throw new Error('Network response was not ok')
   }
   return response.json()
}

const {data} = useQuery(['test'],querFn)

オプション

これは記述の説明で記載しましたcacheTimeなどです。
下記表ではよく使うものをまとめておきます。

オプション名 説明
cacheTime キャッシュの保有時間を設定できる
指定がない場合は5分間。Infinity(永続的)な設定も可能。
staleTime 再フェッチ時に設定されている時間内はAPIなどからデータを持ってこず、キャッシュ値を返すことが可能

最後に

SWRを実現するためにReactでは他にもuseSWRがありますが、TanStack Queryの方がDevtoolsがあったり、React以外にもVueやSolidでも提供されている点から発展の可能性が高いのかなと思っております。
また、Nuxt3でのuseFetchであったりuseAsyncDataも同じようにSWRを実現する機能が色々とでてきておりキャチアップはしっかりとしていければなと思っております。

明日は、@kouki_kubotaさんになります。
よろしくお願いします!

14
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?