【Next.js/React.js】use clientとは何か?サーバーコンポーネントとクライアントコンポーネントの違い

react and nextjs-prograshi(プロぐらし)-kv Next-js
記事内に広告が含まれていることがあります。

Next.jsのApp Routerを触り始めて、まず誰もが突き当たる壁が「use client」という謎の宣言ではないでしょうか。

「エラーが出たからとりあえず1行目に入れてみたけれど、実は意味をよく分かっていない……」という方も多いと思います。

現在のReact開発において、サーバー側で処理を行う「サーバーコンポーネント」と、ブラウザで動く「クライアントコンポーネント」の役割を理解することは、高速でモダンなアプリを作るための必須条件です。

本記事では、初心者の方に向けて「use client」とは何かや、サーバーコンポーネントとクライアントコンポーネントの決定的な違い、そして現場で役立つ使い分けのルールを、簡単に解説しています。


use clientとは何か?

React.jsを使う場合、ファイルの冒頭に "use client"; を記述することがあります。

これは、対象のコンポーネントがブラウザ上で動くことの宣言です。

Next.jsでは、デフォルトではコンポーネントを「サーバーコンポーネント」として扱います。

しかし、ボタンを押して画面を変えるような「動き」を作りたいときは、サーバーではなく「ブラウザ(クライアント)」に仕事をさせなければなりません。その合図がuse clientです。


サーバーコンポーネントとは何か?

サーバーコンポーネントの仕組みとメリット

「サーバーコンポーネント」とは、「サーバー側で、あらかじめHTMLを組み立ててからブラウザに送る仕組み」のことです。

React 18から導入され、Next.jsのApp Routerにおいてデフォルトの動作となっています。

サーバーコンポーネントにすることでページを爆速で表示することができます。

ページを爆速で表示できる理由
  • ブラウザがJavaScriptを読み込んで実行する手間が省ける
  • 完成したHTMLが送られてくるので、ユーザーはすぐにコンテンツを目にすることができる。

なお、データベースからデータを取得するだけならブラウザに任せるよりもサーバーに任せる方が早いです。


サーバーコンポーネントでできないこと

既に完成品を渡すため、ブラウザ(クライアント)側でマウスによる操作やボタンのクリック、入力があった場合に反応することができません。

サーバーコンポーネントでできないこと
  • ユーザーの操作に反応する: onClickonChange は使えません。
  • 状態を保持する: useStateuseEffect は使えません。
  • ブラウザ独自の機能を使う: windowlocalStorage にはアクセスできません。
  • Firebaseと通信を行う:ブラウザに表示された後に他のサーバーと通信することができません。


これらの機能を使いたい場合は、ファイルの冒頭に "use client"; を記述することで、Next.jsに「これはサーバーコンポーネントではなく、クライアントコンポーネントです!」と伝える必要があります。



使い方

使い方は簡単で、ファイルの冒頭(1行目)に引用符で囲って記述します。

"use client"; // これを1行目に書く!

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>クリック回数: {count}</p>
      {/* onClickを使うので "use client" が必須 */}
      <button onClick={() => setCount(count + 1)}>
        増やす
      </button>
    </div>
  );
}


使うのは必要なときだけ!

基本はサーバーコンポーネントで作り、動きが必要なパーツ(ボタンやフォームなど)だけを切り出して use client にするのが基本です。

クライアントコンポーネントにするとブラウザで動かすJavaScriptの量が増えるため、サイトが重くなります。

コンポーネントの機能種類
データの取得、レイアウトの作成サーバー
ヘッダー、フッター、サイドバーサーバー
検索バー、いいねボタン、フォームクライアント (use client)


タイトルとURLをコピーしました