React#
ReactはMetaが開発しているUIのライブラリ。JSX(JavaScript XML)というHTMLライクな記法をJavaScript内で使用できる構文拡張を用いてUIを定義できる
React Hooks#
⚠️ データの取得はuseEffectでは行わないほうがよい#
useEffectを使うことによる問題#
問題1. ウォーターフォール問題
親コンポーネントのデータフェッチが完了するまで、子コンポーネントはデータフェッチが行われないのでパフォーマンスが落ちてしまう
問題2. 競合状態(Race Condition)の発生
以下のようなコードの場合、userIdが素早く変わった場合に古いリクエストが新しいリクエストの後に完了して、古いデータで状態が更新される可能性がある
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]);
対処法#
代わりの方法としては、次のようなフェッチ用ライブラリを使う
対処法1. SWRを使う
SWRはデータ取得のためのReact Hooksライブラリで、Vercelが開発している。
“SWR” という名前は、 HTTP RFC 5861(opens in a new tab) で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。
SWRの実装例
import useSWR from 'swr';
function UserProfile({ userId }) {
const { data: user, error, isLoading } = useSWR(
`/api/users/${userId}`,
fetchUser
);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error occurred</div>;
return <div>{user.name}</div>;
}
対処法2. TanStack Queryを使う
TanStack Queryの実装例
import { useQuery } from '@tanstack/react-query';
function UserProfile({ userId }) {
const { data: user, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId)
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{user.name}</div>;
}