サーバーでのデータ取得
なぜ学ぶか: 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が生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。