0Pricing
Frontend Academy · レッスン

マウント時のデータ取得

useEffect 内で API から JSON を取得し、レスポンスを state に保存し、空の依存配列で取得を一度だけ実行します。

「マウント時のデータ取得」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。

データ取得パターン

React における標準的なデータ取得パターンは次のとおりです。1) loading、error、data の state を定義する、2) 空の依存配列 [] を指定した useEffect でデータを取得する、3) コールバックで state を更新する、4) state に基づいてレンダリングする。

完全な例

マウント時にユーザーを取得し、読み込み中とエラーを処理する完全な例です。

interface User { id: number; name: string; email: string; }

function UserList() {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/users')
      .then(res => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.json();
      })
      .then(data => setUsers(data))
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <Spinner />;
  if (error)   return <ErrorMessage message={error} />;
  return <ul>{users.map(u => <UserItem key={u.id} {...u} />)}</ul>;
}

useEffect での async/await の使用

useEffect のコールバックを直接 async にすることはできません(Promise を返すため、React がそれをクリーンアップ関数として解釈します)。代わりに、内部で async 関数を定義し、すぐに呼び出します。

useEffect(() => {
  async function fetchUsers() {
    try {
      const res = await fetch('/api/users');
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      setUsers(data);
    } catch (err) {
      setError((err as Error).message);
    } finally {
      setLoading(false);
    }
  }

  fetchUsers();
}, []);

レスポンスステータスの確認

fetch は HTTP エラー(4xx、5xx)では例外をスローせず、ネットワーク障害の場合にのみスローします。必ず response.ok を確認し、エラーレスポンスの場合は手動で例外をスローしてください。

const res = await fetch('/api/data');
if (!res.ok) {
  // Could also use res.status for specific handling
  throw new Error(`Server responded ${res.status}: ${res.statusText}`);
}
const data = await res.json();

依存関係の変更時にデータを取得する

ルートパラメーターや props の ID などの依存関係を、エフェクトの依存配列に追加します。依存関係が変化するたびにエフェクトが再実行され、最新のデータを取得します。

const { userId } = useParams();

useEffect(() => {
  if (!userId) return;
  setLoading(true);
  fetch(`/api/users/${userId}`)
    .then(r => r.json())
    .then(setUser)
    .finally(() => setLoading(false));
}, [userId]);

エフェクトでの POST リクエスト

エフェクトから POST/PUT/DELETE リクエストを送信することもできますが、通常これらはマウント時のエフェクトではなく、イベント(フォームの送信やボタンのクリック)によって実行します。データの読み込みにはエフェクトを使用し、ミューテーションにはイベントハンドラーを使用してください。

カスタム useFetch フック

fetch、loading、error のパターンをカスタムフックに切り出すと、複数のコンポーネントで再利用できます。

function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(r => { if (!r.ok) throw new Error(`${r.status}`); return r.json(); })
      .then(setData)
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

JSON の安全なパース

res.json() は必ず try/catch で囲んでください。形式が不正な JSON では SyntaxError がスローされます。外側の catch で処理できますが、発生元を把握しておくとデバッグに役立ちます。

API ベース URL の設定

API の URL をハードコードしないでください。ベース URL には環境変数(import.meta.env.VITE_API_URL)を使用します。設定済みの fetch ラッパーを含む api.ts ファイルを中央に作成してください。

const API_BASE = import.meta.env.VITE_API_URL;

async function apiFetch<T>(path: string): Promise<T> {
  const res = await fetch(`${API_BASE}${path}`, {
    headers: { 'Authorization': `Bearer ${getToken()}` }
  });
  if (!res.ok) throw new Error(`API error ${res.status}`);
  return res.json();
}

React Query に移行するタイミング

単純なケースでは、手動の fetch パターンで対応できます。キャッシュ、バックグラウンドでの再取得、ページネーション、ミューテーションが必要になったら、React Query(TanStack Query)に移行してください。これらのパターンを確実に処理できます。

読み込みスケルトンの表示

スピナーの代わりに、読み込み後のコンテンツの形状に合わせたスケルトン UI を表示します。これにより体感の読み込み時間を短縮し、レイアウトシフトを防止できます。

確認問題

useEffect のコールバックを直接 async にできないのはなぜですか?

まとめ:useEffect でのデータ取得

loading、error、data の state を定義します。空の依存配列 [] を指定した useEffect でデータを取得します。内部で async 関数を定義し、コールバック自体を async にはしません。必ず res.ok を確認します。動的にデータを取得する場合は、URL や ID を依存配列に追加します。再利用するには、useFetch カスタムフックに切り出します。本番環境でのデータ取得には TanStack Query の利用を検討してください。

よくある質問

「マウント時のデータ取得」レッスンは無料ですか?

はい。「マウント時のデータ取得」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。

「マウント時のデータ取得」で何を学びますか?

useEffect 内で API から JSON を取得し、レスポンスを state に保存し、空の依存配列で取得を一度だけ実行します。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Frontend Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「マウント時のデータ取得」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このFrontend Academyレッスンでコードを書いて実行できますか?

はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. useEffect の基本:依存関係とクリーンアップ
  2. マウント時のデータ取得
  3. ローディング状態とエラー状態の処理
  4. クリーンアップのための AbortController
← Frontend Academyに戻る