1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js15】サーバーコンポーネントとクライアントコンポーネントの違い

1
Posted at

はじめに

Next.js 15 を使っていると、こんな記述を見かけることがあります。

"use client";

これはクライアントコンポーネントを宣言するためのディレクティブです。では、これを書かない場合は何になるのか?そもそも 2 種類のコンポーネントの何が違うのか?

本記事では、Next.js 15 におけるサーバーコンポーネントクライアントコンポーネントの違いと使い分けについて解説します。

2種類のコンポーネント

Next.js 15 では、コンポーネントは以下の 2 種類に分かれています。

  • サーバーコンポーネント(Server Component)
  • クライアントコンポーネント(Client Component)

大きな違いはどこで実行されるかです。

サーバーコンポーネント

概要

サーバーコンポーネントは、サーバー側で実行されるコンポーネントです。

Next.js 15 では、"use client" の宣言がないコンポーネントはすべてサーバーコンポーネントとして扱われます。つまり、デフォルトがサーバーコンポーネントです。

特徴

  • サーバー側で HTML を生成し、ブラウザに返す
  • データベースや外部 API へ直接アクセスできる
  • コンポーネントの JavaScript コードがブラウザに送られないため、セキュリティ面で有利
  • useState / useEffect などの React フックは使用不可
  • ボタンのクリックなどのユーザー操作を扱えない

コード例

// app/page.tsx(サーバーコンポーネント)

const Page = async () => {
  // サーバー側でデータを取得する
  const res = await fetch("<https://jsonplaceholder.typicode.com/posts/1>");
  const post = await res.json();

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
};

export default Page;

async/await を使ったデータ取得をコンポーネント内に直接書けるのが、サーバーコンポーネントの大きな特徴です。

クライアントコンポーネント

概要

クライアントコンポーネントは、ブラウザ(クライアント)側で実行されるコンポーネントです。

ファイルの先頭に "use client" を宣言することで、そのコンポーネントはクライアントコンポーネントとして扱われます。

特徴

  • useState / useEffect などの React フックが使用可能
  • ボタンのクリックなどのユーザー操作を扱える
  • localStorage などのブラウザ API にアクセスできる
  • コンポーネントの JavaScript がブラウザに送信される

コード例

// app/components/Counter.tsx(クライアントコンポーネント)
"use client";

import { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
};

export default Counter;

useStateonClick を使う場合は、必ず "use client" の宣言が必要です。宣言がないとエラーになります。

2つの違いを比較する

サーバーコンポーネント クライアントコンポーネント
実行場所 サーバー ブラウザ
デフォルト ❌("use client" が必要)
useState / useEffect ❌ 使用不可 ✅ 使用可能
イベントハンドラ(onClick など) ❌ 使用不可 ✅ 使用可能
DB・API への直接アクセス ✅ 可能 ❌ 不可
ブラウザ API(localStorage など) ❌ 使用不可 ✅ 使用可能

使い分けの基本方針

コンポーネントを作る際の判断基準は以下のとおりです。

サーバーコンポーネントを選ぶケース

  • データを取得して表示するだけのコンポーネント
  • SEO 対策が必要なページ
  • 外部 API やデータベースへのアクセスが必要な処理

クライアントコンポーネントを選ぶケース

  • ボタンのクリックやフォーム入力などユーザー操作が必要
  • useState / useEffect を使う状態管理が必要
  • localStorage などブラウザ固有の API を使う

基本的な考え方として、まずサーバーコンポーネントとして実装し、ユーザー操作や状態管理が必要になった時点でクライアントコンポーネントに切り替えるのが推奨されるアプローチです。

組み合わせて使う

実際の開発では、サーバーコンポーネントの中にクライアントコンポーネントを配置する構成が一般的です。

// app/page.tsx(サーバーコンポーネント)
import Counter from "./components/Counter"; // クライアントコンポーネント

const Page = async () => {
  const res = await fetch("<https://jsonplaceholder.typicode.com/posts/1>");
  const post = await res.json();

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
      {/* クライアントコンポーネントを埋め込む */}
      <Counter />
    </div>
  );
};

export default Page;

ページ全体のデータ取得はサーバーコンポーネントで行い、インタラクティブな部分のみをクライアントコンポーネントとして切り出すことで、パフォーマンスとセキュリティのバランスを保つことができます。

まとめ

  • Next.js 15 ではデフォルトがサーバーコンポーネント
  • "use client" を宣言するとクライアントコンポーネントになる
  • サーバーコンポーネントはデータ取得・セキュリティに適している
  • クライアントコンポーネントはユーザー操作・状態管理に適している
  • まずサーバーコンポーネントで実装し、必要な部分だけクライアントコンポーネントにするのが基本方針

2 種類のコンポーネントを適切に使い分けることで、パフォーマンスの高いアプリケーションを構築できます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?