React#

ReactはMetaが開発しているUIのライブラリ。JSX(JavaScript XML)というHTMLライクな記法をJavaScript内で使用できる構文拡張を用いてUIを定義できる

https://ja.react.dev/

React Hooks#

【図解解説】これ1本12分でReact Hooks 全20種を理解できる教科書 #TypeScript - Qiita

⚠️ データの取得は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)、最後に最新のデータを持ってくるという戦略です。

データ取得のための React Hooks ライブラリ – SWR

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

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>;
}