8
7

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.

【React】useQueryについて

Posted at

この記事の目的

  • Reactの理解とアウトプット、振り返り用
  • Reactでよく使われている基本的な技術を言語化できるようする
  • TanStack Query(React Query)について

概要

  • TanStack Queryとは
  • TanStack Queryインストール
  • TanStack Query使用例
  • まとめ
  • 【番外】Tanstack Queryを使用しない場合

TanStack Query(React Queryとは

Tanstack Queryを簡単に説明するとサーバの状態(データ)をfetching, caching, synchronizing and updating(サーバ上のデータをフェッチ、キャッシュ、同期、更新)することができるdata fetchingライブラリです

簡単に言うと、APIとのやりとりをすごく楽にしてくれるライブラリのこと

因みにバージョン3まではReact Queryと呼ばれていましたがバージョン4になり名称がTanStack Queryに変更なり
TanStack QueryになったことでReactだけではなくSolid, Vue, Svelteなどでも利用できるみたいです。

TanStack Queryインストール

npm install -D @tanstack/react-query

TanStack Query使用例

実装内容

  • api/tasksというタスク一覧が取得できるAPIから情報取得を行う
  • resources/ts/pages/tasks/index.tsxで取得処理記載
resources/ts/App.tsx
import React from 'react';
import { Router } from "./Router";
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            retry: false
        },
        mutations: {
            retry: false
        }
    }
});

export const App = () => {
    return (
        <QueryClientProvider client={queryClient}>
            <Router />
        </QueryClientProvider>
    )
}

設定できるオプションには以下のようなものがあるみたいです。一部抜粋

オプション名 説明
retry デフォルトで3回まで失敗してもフェッチをする設定になっていますが、falseを指定すれば無効化できる。
refetchOnWindowFocus デフォルトでユーザーがブラウザのコンポーネントにフォーカスを当てた時に自動でフェッチが動くようになっている。
レンダリングが多く行われることになりかねないので、できればfalseにしておく。
suspense trueにすることで、最初のデータ取得完了までSuspenseにフォールバックしてくれる。
そのため適当な粒度でSuspenseを差し込んでおけばデータがnullかどうかを気にせずほぼ同期的に扱える
resources/ts/pages/tasks/index.tsx
import React from 'react';
import axios from 'axios';
import { useQuery } from '@tanstack/react-query';

type Task = {
    id: number
    title: string
    is_done: boolean
    created_at: Date
    updated_at: Date
}

export const TaskPage = () => {
    // 第一引数:キーとなる文字列
    // 第二引数:非同期の処理
    // useQueryから受け取るのはdate(APIから取得したタスクの一覧)とstatus(エラーやローディング情報)
    const { data:tasks, status} = useQuery(['tasks'],async () =>{
        const { data } = await axios.get<Task[]>('api/tasks')
        return data
    })

    // 返却されたステータスとタスクの中身によって画面表示を変更
    if (status === 'loading') {
        return <div className="loader" />
    } else if (status === 'error') {
        return <div className="align-center">データの読み込みに失敗しました</div>
    } else if (!tasks || tasks.length <= 0) {
        return <div className="align-center">登録されたTodoはありません</div>
    }
    // ここから下は取得したタスクを画面表示しているだけです。
    return (
        <>
            <div className="inner">
                <ul className="task-list">
                    { tasks.map(task => (
                        <li key={ task.id }>
                            <label className="checkbox-label">
                                <input type="checkbox" className="checkbox-input" />
                            </label>
                            <div><span>{ task.title }</span></div>
                            <button className="btn is-delete">削除</button>
                        </li>
                    ))}
                </ul>
            </div>
        </>
    );
}

【番外】バージョンでのエラー

今回は@tanstack/react-query": "^4.24.10"とバージョン4を使用しているのですが、下記のようなエラーが出るかもしれないです。

query.ts:359 As of v4, queryKey needs to be an Array. If you are using a string like 'repoData', please change it to an Array, e.g. ['repoData']

このエラーが出た際は

resources/ts/pages/tasks/index.tsx
const { data:tasks, status} = useQuery('tasks',async () =>{

上記を下記のようにしてください。バージョン4以降でuseQueryの第一引数の型が異なるみたいです。

resources/ts/pages/tasks/index.tsx
const { data:tasks, status} = useQuery(['tasks'],async () =>{

まとめ

  • Tanstack Queryは前までReact Queryと呼ばれていた
  • TanStack Queryは、サーバから取得したデータをクライアントでキャッシュとして保管できる
  • 新しいデータを取得したときにいつキャッシュを更新するか、なども管理することができる
  • queryClient:クエリとキャッシュを管理する
  • QueryClientProvider:キャッシュやクライアント設定を下のコンポーネントに与えたり、値としてqueryClientを取得する
  • useQuery():Hooksの一つ。クエリを行うことができる
  • ReactQueryDevTool:TanStack Queryで管理しているデータの変化を確認するための開発者用ツール

【番外】Tanstack Queryを使用しない場合

resources/ts/pages/tasks/index.tsx
import React, { useEffect, useState } from 'react';
import axios from 'axios';

type Task = {
    id: number
    title: string
    is_done: boolean
    created_at: Date
    updated_at: Date
}

export const TaskPage = () => {

    const [tasks, setTasks] = useState<Task[]>([]);

    const getTasks = async () => {
        // 非同期の処理なのでaxiosの前にawaitを記載。axios.get()の引数に取得するAPIのパスを指定
        // 分割代入で{ data }とすることで取得したい部分のみ取得
        const { data } = await axios.get<Task[]>('api/tasks')
        console.log(data);
        setTasks(data);
    }

    useEffect(() => {
        getTasks()
    })

    return (
        <>
            <div className="inner">
                <ul className="task-list">
                    { tasks.map(task => (
                        <li key={ task.id }>
                            <label className="checkbox-label">
                                <input type="checkbox" className="checkbox-input" />
                            </label>
                            <div><span>{ task.title }</span></div>
                            <button className="btn is-delete">削除</button>
                        </li>
                    ))}
                </ul>
            </div>
        </>
    );
}
8
7
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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?