Server / Client Components
なぜ学ぶか: Next.jsのコードで一番大事な概念がこれです。「なぜこのファイルの先頭に'use client'があるのか」が分かると、Next.jsのエラーの多くが意味を持ちます。まず全体の形を見てください。
まずはこの例を見てみましょう
// ===== page.tsx(何も書かない = サーバーで動く)=====export default async function Page() { const posts = await fetchPosts(); // データを取って… return ( <main> {posts.map((p) => <article key={p.id}>{p.title}</article>)} <LikeButton /> {/* クリックが必要な部分だけ、別部品に */} </main> );} // ===== like-button.tsx(ブラウザで動く部品)====="use client"; // ← この1行が「ブラウザ行き」の宣言 export function LikeButton() { const [likes, setLikes] = useState(0); // useState はブラウザ専用 return <button onClick={() => setLikes(likes + 1)}>♥ {likes}</button>;}
ページ本体はサーバー(軽くて速い)、ボタンだけブラウザ(操作できる)。この分担が理想形です。
何も書かなければサーバーで動く
コンポーネントはサーバーで実行され、完成したHTMLになって届きます。ブラウザに送るコードが減り、軽くて速いです。
'use client'=ブラウザ行きの宣言
例のLikeButtonのように、ファイル先頭に書くとブラウザで動きます。useState・onClickなどの「操作する機能」はこちら専用です。
使い分けの原則
データを取って表示するだけ → サーバー。クリック・入力・stateが要る → ブラウザ。「操作が必要な部分だけ」を小さく切り出すのが理想です。
レビュー観点:'use client'の乱発
AIがページ全体に'use client'を付けていたら、サーバーの利点を捨てているサイン。「操作部分だけ分離できない?」が定番の指摘です。
コード例
// ===== app/posts/page.tsx(サーバー: 既定)=====// データを取得して表示するだけ → サーバーで完結export default async function Page() { const posts = await fetchPosts(); return ( <main> <h1>投稿一覧</h1> {posts.map((p) => <article key={p.id}>{p.title}</article>)} <LikeButton /> {/* 対話が必要な部分だけ「ブラウザ」の部品に */} </main> );} // ===== like-button.tsx(ブラウザ)====="use client";import { useState } from "react"; export function LikeButton() { const [likes, setLikes] = useState(0); return <button onClick={() => setLikes(likes + 1)}>♥ {likes}</button>;}
「サーバーの器に、ブラウザの島を埋め込む」構造。AIのコードを読むときは、まず各ファイルの先頭1行('use client'の有無)を見ましょう。
ステップ 1 / 2
※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。