Next.js App Router の登場により、React のコンポーネントモデルが大きく変わりました。Server Components と Client Components の2つの世界を使い分けることが、現代の Next.js 開発の核心です。
Server Components が基本
App Router では、デフォルトですべてのコンポーネントが Server Component です。Server Component はサーバー上でのみ実行され、JavaScript バンドルに含まれません。データフェッチ・DB アクセス・機密情報の取り扱いはここで行います。
- async/await でデータを直接 fetch できる
- クライアントに JS が送られないため高速
- useState / useEffect などの React フックは使えない
- イベントハンドラは持てない
Client Components は境界を明示する
インタラクティブな UI が必要な場合のみ、ファイルの先頭に "use client" ディレクティブを追加します。これはコンポーネントツリーの「境界」を定義します。境界以下のすべてのコンポーネントはクライアント側で実行されます。
typescript
"use client";
// この宣言より下はブラウザで実行される
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}コンポジションパターン
Server Component の中に Client Component を配置することはできますが、逆(Client Component の中で Server Component を直接レンダリング)はできません。ただし、children として Server Component を渡すことは可能です。
Next.js 15 の params は Promise
Next.js 15 から、動的ルートの params と searchParams は Promise 型になりました。コンポーネント内で await して使う必要があります。
typescript
// app/articles/[slug]/page.tsx
export default async function ArticlePage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
// slug を使って記事を取得...
}