React公式では「axios + TanStack Query」推奨
React開発ではfetch単体よりも、フレームワークを使用していない場合は、axios + TanStack Queryのようにオープンソースのソリューションを使用することが推奨されています。
エフェクトでのデータ取得に代わる良い方法は? - React
axiosはfetchの利便性の悪さから使用されているケースが多いですが、TanStack Queryが使用されているケースは少ないです。
axios + TanStack Queryを使用したほうが状態管理コード(useState)がなくなるので、コードの可読性が良くなります。
// fetchのコード
setLoading(true)
try {
const res = await fetch(url)
if (!res.ok) throw new Error('error')
const data = await res.json()
setData(data)
} catch (e) {
setError(e)
} finally {
setLoading(false)
}// axios + TanStack Query のコード
const fetchData = async (url: string) => {
const res = await axios.get(url)
return res.data
}
const {
data,
isLoading,
isError,
error
} = useQuery({
queryKey: ['data', url],
queryFn: () => fetchData(url)
})axios + TanStack Queryを使用したサンプル
まず、baseURL付きのaxiosインスタンスを作成します。
このサンプルではdummyjsonを使用しているため、baseURLが「https://dummyjson.com」になっていますが、一般的なWebサイトであれば「/api」とかになります。
import axios from 'axios'
export const api = axios.create({
baseURL: 'https://dummyjson.com',
timeout: 10000,
})axiosではtimeoutのデフォルト値が0のため、指定しないとどれだけ待ってもタイムアウトしません。
なので、必ずtimeoutの時間をミリ秒で指定してください。
次にTanStack Queryを使用するためのProvider(土台)を用意します。
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
export function AppProvider({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}Providerを用意したらmain.tsxで読み込んで、<AppProvider><App /></AppProvider>のように囲みます。
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { AppProvider } from './providers/AppProvider'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<AppProvider>
<App />
</AppProvider>
</StrictMode>
)最後にApp.tsxでダミーのJSONのAPIを読み込んで表示するコードを以下のように書けば完成です。
Tanstack QueryのuseQueryを使用することで、data, isLoading, isError, errorのそれぞれがuseQueryで取得できるので、状態管理コード(useState)やtry ... catch文を使わない可読性の良いコードになっています。
import { useQuery } from '@tanstack/react-query'
import { api } from './lib/api'
const fetchProducts = async () => {
const res = await api.get('/products?select=title,price&delay=1000')
return res.data
}
function App() {
const { data, isLoading, isError, error } = useQuery({
queryKey: ['products'], // クエリを識別するためのキー
queryFn: fetchProducts, // データを取得する非同期関数
staleTime: 10000, // キャッシュが使われる時間
})
if (isLoading) {
return <p>Loading...</p>
}
if (isError) {
return <p>Error: {(error as Error).message}</p>
}
return (
<>
<h1>Products</h1>
<ul>
{data.products.map((product: any) => (
<li key={product.id}>
{product.title} - ${product.price}
</li>
))}
</ul>
</>
)
}
export default Appaxios + TanStack Query GET sample
Reactの基礎がわかる方であれば、axios + Tanstack Queryが推奨されている理由をこのコードを見ただけで理解することができ、これを使わずにはいられないでしょう。

