【Next.js】コンポーネントの種類と使い分けをコード例で解説
Published: September 7, 2026 · 10 min read
Next.js のコンポーネントの基礎を解説します。サーバーコンポーネントとクライアントコンポーネントの違い、page.tsx や layout.tsx などファイル名の役割、props と children の書き方をコード例つきで紹介します。
Next.js のコンポーネントとは
コンポーネントは、表示を部品に分けた関数です。ヘッダーやボタンのように、同じ見た目を何度も使い回せます。この記事では、Next.js(App Router)のコンポーネントの種類と使い分けを、コード例つきで解説します。
先に要点をまとめると、次の2つです。
1つ目は、コンポーネントはデフォルトのまま書き、useState や onClick が必要な時だけ先頭に "use client" と書くこと。
2つ目は、app フォルダではファイル名が役割を決めること。page.tsx は画面、layout.tsx は共通の枠、loading.tsx は読み込み中の画面、error.tsx はエラー画面を担当します。
props と children の使い方
基本の使い方は props と children の2つです。順に見ます。
props:ページごとに変わる値を渡す
ヘッダーを例にします。タイトルはページごとに変わるので、props で受け取ります。props は読み取り専用で、受け取った側で書き換えることはできません。
type SiteHeaderProps = { title: string };
export function SiteHeader({ title }: SiteHeaderProps) {
return (
<header className="border-b px-4 py-3">
<h1 className="text-lg font-bold">{title}</h1>
</header>
);
}
// 使う側
<SiteHeader title="DesignLayer" />children:タグの中身をそのまま受け取る
カードのように、枠は共通で中身だけ変えたい部品には children を使います。タグの間に書いた要素が、そのまま children として渡されます。
import type { ReactNode } from "react";
export function Card({ children }: { children: ReactNode }) {
return (
<div className="rounded-lg border p-4 shadow-sm">
{children}
</div>
);
}
// 使う側:中身は自由
<Card>
<h2>料金プラン</h2>
<p>月額2,980円</p>
</Card>サーバーコンポーネントとクライアントコンポーネントの違い
App Router では、何も指定しなければサーバーコンポーネントとして動きます。サーバー側で実行されるため、データ取得を直接書けて、ブラウザに送る JavaScript を減らせます。
次のどれかを使いたい場合は、ファイルの先頭に "use client" と書きます。useState や useEffect などのフック、onClick などのイベント、window や localStorage などのブラウザ API です。どれも使わなければ、何も書かなくて大丈夫です。
クライアントコンポーネントの例
"use client"; // これが必須
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}"use client" を忘れるとエラーになる
"use client" を書かずに useState を使うと、ビルド時にエラーになります。このエラーが出たら、そのファイルに "use client" が必要かどうかを確認してください。
アニメーションライブラリ(Framer Motion など)や、ホバーで動く UI もクライアントコンポーネントが必要です。
サーバーとクライアントを組み合わせる時のルール
クライアントコンポーネントの中に置いた部品は、すべてクライアントコンポーネントとして扱われます。
サーバーコンポーネントからクライアントコンポーネントを読み込むことはできますが、逆はできません。
そのため、ページはサーバーコンポーネントのままにして、動きのある部品だけをクライアントコンポーネントにする分け方が一般的です。
app フォルダのファイル名と役割(page / layout / loading / error)
app フォルダでは、決められたファイル名に役割が割り当てられています。よく使うものを順に見ます。
page.tsx:その URL の画面
URL に対応する画面を書くファイルです。
export default function Home() {
return <h1>Home Page</h1>;
}layout.tsx:ページをまたいで残る枠
ヘッダーやサイドバーなど、配下のページで共有する部分を書きます。ページ遷移しても状態(スクロール位置など)が維持されます。
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<header>Header</header>
<main>{children}</main>
<footer>Footer</footer>
</div>
);
}loading.tsx:読み込み中に自動で出る画面
同じフォルダに置くだけで、データ取得中に自動表示されます。スケルトンスクリーンを置く場所はここです。
export default function Loading() {
return <p>Loading...</p>;
}error.tsx:エラー時の画面("use client" 必須)
"use client";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>エラーが発生しました</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>再試行</button>
</div>
);
}template.tsx・not-found.tsx・middleware.ts
template.tsx — layout に似ていますが、遷移のたびに再マウントされます。入場アニメーションを毎回再生したい時に使います。
not-found.tsx — 404 画面をカスタマイズします。
middleware.ts — コンポーネントではありませんが、リクエスト時に認証チェックやリダイレクトを挟む仕組みです。
コンポーネント設計の基本:1ファイル1役割に分ける
1つのコンポーネントに「データ取得・表示・ボタンの処理」を全部まとめると、あとから直しにくくなります。
分け方は、データ取得はサーバーコンポーネント(page.tsx など)、表示は props を受け取るだけの部品、操作はクライアントコンポーネント、という3つです。役割ごとに分けると、直したい場所をすぐに見つけられます。
// サーバーコンポーネント:取得だけ担当
async function PostsPage() {
const posts = await fetchPosts();
return <PostList posts={posts} />;
}
// 表示だけ担当する部品(props を受け取るだけ)
function PostList({ posts }: { posts: Post[] }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}汎用コンポーネントは自作せずコピーして使う
ここまでの内容で自作できます。ただ、ボタンやフォームのような汎用的な部品を毎回ゼロから書く必要はありません。
よく使われているのが shadcn/ui です。ライブラリとして追加するのではなく、コンポーネントのソースを自分のリポジトリにコピーする方式なので、あとから自由に改造できます。追加は次のコマンドです。
npx shadcn@latest add buttonアニメーション付きセクションはコピーして使う
入場アニメーションやスクロール連動のセクションは、自分で書くと1ブロックに半日かかることもあります。こういう部品は、カタログからコピーして使うのが早いです。
DesignLayer では、アニメーション付きの React セクションをブラウザ上で動かして確認し、TSX + Tailwind のソースをそのままコピーできます。"use client" や必要なパッケージの一覧も含まれているので、そのまま貼って動かせます。
コピーしたあとは Cursor や Claude に貼り、「既存の色や余白に合わせて」と指示すると、文言や色の差し替えもまとめてできます。
まとめ:Next.js コンポーネントの使い分け
・コンポーネントはデフォルト(サーバー)で書き、状態やイベントが必要な時だけ "use client" を書く
・app フォルダではファイル名が役割を持つ。page / layout / loading / error を使い分ける
・値の受け渡しは props、中身を包む部品は children で作る
・汎用部品は shadcn/ui、アニメーション付きセクションは DesignLayer のカタログからコピーすると早い
DesignLayer のコンポーネントカタログは、閲覧無料・カード不要です。ライブプレビューで動きを確認し、無料枠(1日1回)で1セクションを自分のプロジェクトに貼ってみてください。無制限コピーと完成1ページの Templates は Pro(月額2,980円・税込)で利用できます。