コンテンツへスキップ
アプリケーションの構築レンダリングクライアントコンポーネント

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

クライアントコンポーネントを使用すると、サーバーでプリレンダリングされるインタラクティブなUIを作成でき、クライアントJavaScriptをブラウザで実行できます。

このページでは、クライアントコンポーネントがどのように動作し、どのようにレンダリングされ、いつ使用すべきかについて説明します。

クライアントレンダリングの利点

クライアントでレンダリング作業を行うことには、いくつかの利点があります。

  • インタラクティブ性: クライアントコンポーネントは、状態、エフェクト、イベントリスナーを使用できるため、ユーザーに即座にフィードバックを提供し、UIを更新できます。
  • ブラウザAPI: クライアントコンポーネントは、Geolocation APIlocalStorageといったブラウザAPIにアクセスできます。

Next.jsでのクライアントコンポーネントの使用

クライアントコンポーネントを使用するには、ファイルの一番上、importの前にReactの"use client" ディレクティブを追加します。

"use client"は、サーバーとクライアントコンポーネントモジュールの間に境界を宣言するために使用されます。これにより、ファイル内で"use client"を定義すると、子コンポーネントを含むそのファイルにインポートされる他のすべてのモジュールがクライアントバンドルの一部とみなされます。

app/counter.tsx
'use client'
 
import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

下の図は、ネストされたコンポーネント(toggle.js)でonClickuseStateを使用した場合、"use client"ディレクティブが定義されていないとエラーが発生することを示しています。これは、デフォルトではApp Router内のすべてのコンポーネントがサーバーコンポーネントであり、これらのAPIが利用できないためです。toggle.js"use client"ディレクティブを定義することで、ReactにこれらのAPIが利用可能なクライアント境界に入るように指示できます。

Use Client Directive and Network Boundary

複数のuse clientエントリーポイントの定義:

Reactコンポーネントツリー内に複数の「use client」エントリーポイントを定義できます。これにより、アプリケーションを複数のクライアントバンドルに分割できます。

ただし、クライアントでレンダリングする必要があるすべてのコンポーネントに"use client"を定義する必要はありません。境界を定義すると、すべての子コンポーネントおよびそこにインポートされるモジュールは、クライアントバンドルの一部とみなされます。

クライアントコンポーネントはどのようにレンダリングされますか?

Next.jsでは、クライアントコンポーネントは、リクエストが全ページ読み込み(アプリケーションへの初回アクセスまたはブラウザのリフレッシュによるページ再読み込み)の一部であるか、その後のナビゲーションであるかによって、異なる方法でレンダリングされます。

全ページ読み込み

初回ページ読み込みを最適化するために、Next.jsはReactのAPIを使用して、クライアントコンポーネントとサーバーコンポーネントの両方について、サーバー上で静的なHTMLプレビューをレンダリングします。これは、ユーザーがアプリケーションを初めて訪れたときに、クライアントがクライアントコンポーネントのJavaScriptバンドルをダウンロード、解析、実行するのを待つことなく、すぐにページのコンテンツを見ることができることを意味します。

サーバー側で

  1. Reactはサーバーコンポーネントを、クライアントコンポーネントへの参照を含むReact Server Component Payload (RSC Payload)と呼ばれる特殊なデータ形式にレンダリングします。
  2. Next.jsは、RSC PayloadとクライアントコンポーネントのJavaScript命令を使用して、サーバー上でルートのHTMLをレンダリングします。

その後、クライアント側で

  1. HTMLは、ルートの高速で非インタラクティブな初回プレビューを即座に表示するために使用されます。
  2. React Server Components Payloadは、クライアントコンポーネントツリーとサーバーコンポーネントツリーを調整し、DOMを更新するために使用されます。
  3. JavaScript命令は、クライアントコンポーネントをハイドレートし、そのUIをインタラクティブにするために使用されます。

ハイドレーションとは?

ハイドレーションとは、静的なHTMLをインタラクティブにするために、DOMにイベントリスナーをアタッチするプロセスです。内部的には、ハイドレーションはReact APIのhydrateRootで行われます。

その後のナビゲーション

その後のナビゲーションでは、クライアントコンポーネントはサーバーレンダリングされたHTMLなしで、完全にクライアント側でレンダリングされます。

これは、クライアントコンポーネントのJavaScriptバンドルがダウンロードされ、解析されることを意味します。バンドルの準備ができたら、ReactはRSC Payloadを使用してクライアントとサーバーのコンポーネントツリーを調整し、DOMを更新します。

サーバー環境に戻る

"use client"境界を宣言した後でも、サーバー環境に戻りたい場合があります。たとえば、クライアントバンドルサイズを削減したり、サーバーでデータをフェッチしたり、サーバーでのみ利用可能なAPIを使用したい場合などです。

クライアントコンポーネント内に理論的にネストされていても、クライアントコンポーネントとサーバーコンポーネント、およびサーバーアクションを交互に配置することで、サーバー上にコードを保持できます。詳細については、コンポジションパターンのページを参照してください。