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

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

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

このページでは、クライアントコンポーネントの仕組み、レンダリング方法、および使用する場合について説明します。

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

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

  • インタラクティビティ: クライアントコンポーネントは、状態、効果、イベントリスナーを使用できるため、ユーザーに即座にフィードバックを提供し、UIを更新できます。
  • ブラウザAPI: クライアントコンポーネントは、ジオロケーションlocalStorageなどのブラウザAPIにアクセスできます。

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

クライアントコンポーネントを使用するには、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サーバーコンポーネントペイロード(RSCペイロード)**と呼ばれる特別なデータ形式にレンダリングします。これには、クライアントコンポーネントへの参照が含まれています。 (Reactサーバーコンポーネントペイロード(RSCペイロード))
  2. Next.jsは、RSCペイロードとクライアントコンポーネントのJavaScript命令を使用して、サーバー上でルートの**HTML**をレンダリングします。

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

  1. HTMLを使用して、ルートの高速な非インタラクティブな初期プレビューをすぐに表示します。
  2. Reactサーバーコンポーネントペイロードを使用して、クライアントとサーバーのコンポーネントツリーを調整し、DOMを更新します。
  3. JavaScript命令は、クライアントコンポーネントをハイドレートし、UIをインタラクティブにします。

ハイドレーションとは何ですか?

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

後続のナビゲーション

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

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

サーバー環境に戻る 境界を宣言した後、サーバー環境に戻りたい場合があります。たとえば、クライアントバンドルサイズを削減したり、サーバー上でデータを取得したり、サーバー上でのみ使用可能なAPIを使用したりする場合などです。

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