← inaro.devAI駆動開発 学習ツール
中級

サーバーでのデータ取得

なぜ学ぶか: App Routerでは「コンポーネントの中で直接await fetchする」という、Reactだけ学んだ人には奇妙に見える書き方が標準です。でもこれ、実はいちばんシンプルな形です。例を見てください。

まずはこの例を見てみましょう

// サーバーのコンポーネントは async にできる
export default async function PostsPage() {
  // コンポーネントの中で直接データを取る!
  const res = await fetch("https://api.example.com/posts");
  const posts = await res.json();

  return (
    <ul>
      {posts.map((p) => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}
// useState も useEffect も出てこない

「取って、表示する」だけ。サーバーで完成したHTMLが届くので、ちらつきもありません。

サーバーのコンポーネントはasyncにできる

例のように関数にasyncを付けて、中で直接awaitできます。useEffectもuseStateも不要です。

描画の前にデータが揃う

サーバーで「取得 → HTML生成」まで終えてから届くので、ローディングのちらつきがなく、検索エンジンにも完成品が見えます。

使い分け

最初に表示するデータ → サーバーで取る。ユーザー操作に応じた追加取得(検索など)→ ブラウザで取る。「最初の絵はサーバー、動きはブラウザ」です。

AIの古い書き方に注意

最初のデータを「useEffect + useState + fetch」の旧スタイルで取ることがあります。「サーバーで直接取れない?」が定番レビューです。

コード例

// app/posts/page.tsx — サーバーでのデータ取得(標準形)
type Post = { id: number; title: string };

export default async function PostsPage() {
  // コンポーネント内で直接 await(サーバーで実行される)
  const res = await fetch("https://api.example.com/posts");
  if (!res.ok) throw new Error("取得に失敗しました");

  const posts: Post[] = await res.json();

  return <ul>{posts.slice(0, 5).map((p) => <li key={p.id}>{p.title}</li>)}</ul>;
}

Phase 01でやったfetchの3段階(送る→確認→取り出す)がそのまま出てきています。if (!res.ok)も忘れずに。

ステップ 1 / 2

※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。