0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ReactとNext.jsでTanstackQueryの導入をやってみた

Posted at

TanstackQueryとは?

TanstackQueryとは、データ取得する際に使われるライブラリです。
公式ドキュメントから引用するとWebアプリケーションでのサーバー状態の取得、キャッシュ、同期、更新が非常に簡単になります。

公式ドキュメント

公式ドキュメント
公式ドキュメント(概要)

インストール

React(npm)で進めて行きます。yarnを使っているならyarn、pnpmならpnpmでやってください。
コマンドが少し変わるので公式ドキュメントから確認してください。

npm i @tanstack/react-query

公式ドキュメントのインストール

従来のデータフェッチ(インターネット上から情報を取ってくること)のやり方

以前はuseEffectやuseStateなどを使っていました。

Posts.tsx
import { useState, useEffect } from 'react'
import axios from 'axios'

const Posts = () => {
    const [data, setData] = useState([]);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        const fetchPosts = async () => {
            try {
                setIsLoading(true);
                const response = await axios.get(
                    "***********"
                );
                setData(response.data);
                setError(null);
            } catch (err) {
                setError(err.message);
            } finally {
                setIsLoading(false);
            }
        };

        fetchPosts();
    }, []); // 空配列 = コンポーネントが最初に表示されたときだけ実行

    if (isLoading) return <div>読み込み中...</div>;
    if (error) return <div>エラー: {error}</div>;

    return (
        <div>
            <h1>投稿一覧</h1>
            <div>{data.map((post) => (
                <p key={post.id}>
                    <a href="/">{post.title}</a>
                </p>
            ))}</div>
        </div>
    )
}

export default Posts

従来のやり方の問題点

上記のコードくらいのuseStateやuseEffectの数なら、そんなに大した問題ではないのですが、
実際に稼働しているWebサービスだったらどうでしょうか?

大規模アプリで発生する問題

1.同じコードの繰り返し
APIからデータを取得するたびに、毎回以下を書く必要があります。💦

const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => { /* データ取得処理 */ }, []);

APIが10、20、100と増えていくたびに、このコードも同じだけ増えていきます。😱

2.重複したデータ取得

//Postsページ → ユーザー情報を取得
// Profileページ → 同じユーザー情報をまた取得
// Headerコンポーネント → また同じユーザー情報を取得
// → 無駄なAPI呼び出しが大量発生!

3.キャッシュ管理が大変

一度取得したデータを再利用したいけど、データが古くなったら再取得したい
この管理を自分でやるのは非常に大変😅

4.状態管理の複雑化
大量のuseStateとuseEffectを書くと、どこで何を管理しているのか分からなくなります。😭
コードが肥大化してぐちゃぐちゃになって行きます。

これらを解決するために生まれたのが
TanstackQueryです。

TanstackQueryでのデータフェッチ

queryClientをインスタンス化して、QueryClientProviderでComponentを囲みます。

App.tsx
import './App.css'
import Posts from './components/Posts'
import {
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'

const queryClient = new QueryClient() // queryClientをインスタンス化

function App() {
  // QueryClientProviderでComponentを囲む
  return ( 
    <QueryClientProvider client={queryClient}>
      <Posts />
    </QueryClientProvider>
  )
}

export default App

公式ドキュメントの概要

useQueryを呼び出す

useQueryを呼び出していく必要があります。はjsonplaceholderを使ってます。
ここでデータを取得してきて、画像はjsonplaceholderから取得してきたものです。
動画はわかりやすいので良かったら見てみてください。
あとコードはかなりシンプルになったかと思います。

components/Posts.tsx
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'

const Posts = () => {
 const { data, isLoading, error } = useQuery({
  queryKey: ["posts"],
    queryFn: async () => {
     const { data } = await axios.get(
       "https://jsonplaceholder.typicode.com/posts"
     );
       return data;
    },
  });

  if (isLoading) return <div>読み込み中...</div>;
  if (error) return <div>エラー: {error.message}</div>;

  return (
    <div>
      <h1>投稿一覧</h1>
      <div>{data.map((post) => (
          <p key={post.id}>
            <a href="/">{post.title}</a>
          </p>
         ))}
      </div>
    </div>
    )
}

export default Posts

公式ドキュメントuseQuery

スクリーンショット 2025-10-27 2.39.38.png

導入メリット

1.コードがシンプルになる

useStateやuseEffectを自分で書く必要がなく。
ローディング、エラー、データの状態を自動管理

2.自動キャッシュ機能
一度取得したデータは自動でキャッシュされ、
同じデータを複数のコンポーネントで使っても、API呼び出しは1回だけで済みます。

3.自動で再取得
データが古くなったら自動で再取得して、
ウィンドウにフォーカスが戻ったら最新データを取得します。

4.保守性の向上
データ取得のロジックが一箇所に集約するので、大規模アプリでも管理しやすいです。

結論(TanStack Queryはなぜ生まれたか)

大規模なアプリで発生する「無駄なデータ取得」と「煩雑な状態管理」を解決するために生まれました。

参考動画

useEffectよりも優れたデータフェッチング方法【TanstackQuery入門】

説明

補足

ClaudeCodeにも文章を書くの少し手伝ってもらっています。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?