Reactのデータフェッチにはライブラリを使おう(Tanstack Query)
Reactでデータフェッチをするときには、ライブラリを使用した方が色々ありがたいお話です。
ライブラリを使用しない方法
ライブラリを使用しない従来の書き方になると、useStateとuseEffectを使用することになるでしょうか。
import { useEffect, useState } from "react"
import axios from "axios"
function ExampleWithoutuseQuery() {
const [data, setData] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
// ローディング開始
setIsLoading(true)
const res = await axios.get("/api/todos");
setData(res.data);
} catch (err: any) {
setError(err)
} finally {
// ローディング終了
setIsLoading(false);
}
}
// 初回マウント時にフェッチ関数を走らす
fetchData();
}, []);
// ローディングUI
if (isLoading) return <p>Loading...</p>
// エラー時に表示するUI
if (error) return <p>Error occurred</p>
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
このようにuseStateとuseEffectを使用して、自作で動きを管理する必要があります。
また、キャッシュや自動リフェッチが必要な場合も、自作しなければなりません。
useQueryを使用
import { useQuery } from "@tanstack/react-query"
import axios from "axios"
function Example() {
const { data, isLoading, error } = useQuery({
queryKey: ["todos"], // キャッシュのキー
queryFn: async () => {
const res = await axios.get("/api/todos")
return res.data
},
})
if (isLoading) return <p>Loading...</p>
if (error) return <p>Error occurred</p>
return (
<ul>
{data.map((todo: any) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
このようにuseQuery側でデータやローディング、エラーの管理をしてくれます。他にも色々。
キャッシュで無駄なリクエストを削減し、自動リフェッチで最新データを維持します。