Client Components
Client Componentsを使用すると、インタラクティブなUIを作成できます。これはサーバーでプリレンダリングされ、クライアントJavaScriptを使用してブラウザで実行できます。
このページでは、Client Componentsがどのように機能するか、どのようにレンダリングされるか、いつそれらを使用するのかを解説します。
クライアントレンダリングの利点
クライアントでレンダリング作業を行うことには、いくつかの利点があります:
- インタラクティビティ:Client Componentsは状態、エフェクト、およびイベントリスナーを使用できるため、ユーザーに即時フィードバックを提供し、UIを更新できます
- ブラウザのAPI:Client ComponentsはgeolocationやlocalStorageなどのブラウザAPIにアクセスできます
Next.jsでのClient Componentsの使用
Client Componentsを使用するには、ファイルの上部、インポートの前にReactの"use client"
ディレクティブを追加します。
"use client"
は、サーバーとClient Componentモジュール間の境界を宣言するために使用されます。つまり、ファイル内で"use client"
を定義することで、それにインポートされるすべてのモジュール、子コンポーネントも含めて、クライアントバンドルの一部と見なされます。
- TypeScript
- JavaScript
'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>
)
}
'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
)でonClick
やuseState
を使用することが"use client"
ディレクティブが定義されていない場合にエラーを引き起こすことを示しています。これはデフォルトでは、App Router内のすべてのコンポーネントがこれらのAPIが利用できないServer Componentsだからです。toggle.js
内で"use client"
ディレクティブを定義することで、これらのAPIを利用できるクライアントの境界にReactを入れることができます。
複数の
use client
エントリーポイントを定義する:React Component treeに複数の"use client"エントリーポイントを定義することができます。これにより、アプリケーションを複数のクライアントバンドルに分割できます。
しかし、クライアントでレンダリングされる必要があるすべてのコンポーネントに
"use client"
を定義する必要はありません。一度境界を定義すると、それにインポートされるすべての子コンポーネントとモジュールは、クライアントバンドルの一部と見なされます。
Client Componentsはどのようにレンダリングされるのか?
Next.jsでは、Client Componentsはリクエストがフルページロード(アプリケーションへの初回訪問や、ブラウザのリフレッシュによるページリロード)か、その後のナビゲーションの一部であるかによって、異なる方法でレンダリングされます。
フルページロード
初期ページロードを最適化するために、Next.jsはReactのAPIを使用して、ClientおよびServer Componentsの静的HTMLプレビューをサーバーでレンダリングします。これは、ユーザーが初めてアプリケーションを訪れたとき、クライアントがClient Component JavaScriptバンドルをダウンロード、解析、および実行するのを待つことなく、ページの内容を即座に表示できることを意味します。
サーバー上で:
- ReactはServer Componentsを、Client Componentsへの参照を含む特別なデータ形式であるReact Server Component Payload (RSC Payload)にレンダリングします
- Next.jsはRSC PayloadとClient Component JavaScript命令を使用して、サーバー上でルートのHTMLをレンダリングします
次に、クライアント上で:
- HTMLが使用され、ルートの迅速で非インタラクティブな初期プレビューが即座に表示されます
- React Server Components Payloadが使用され、ClientとServer Component treesが整合し、DOMが更新されます
- JavaScript命令が使用され、Client Componentsがハイドレートされ、UIがインタラクティブになります
ハイドレーションとは何か?
ハイドレーションは、静的HTMLをインタラクティブにするために、DOMにイベントリスナーをアタッチするプロセスです。裏で、ハイドレーションは
hydrateRoot
React APIで行われます。
続いてのナビゲーション
その後のナビゲーションでは、Client ComponentsはサーバーレンダリングされたHTMLなしでクライアント上で完全にレンダリングされます。
これは、Client Component JavaScriptバンドルがダウンロードおよび解析されることを意味します。バンドルが準備できたら、ReactはRSC Payloadを使用してClientとServer Component treesを整合し、DOMを更新します。
サーバー環境に戻る
場合によっては、"use client"
の境界を宣言した後でもサーバー環境に戻りたいことがあります。たとえば、クライアントバンドルのサイズを削減したい場合や、サーバーでしか利用できないAPIを使用したい場合です。
Client Components内に理論的にはネストされている場合でも、ClientとServer ComponentsおよびServer Actionsを交互に組み合わせることでコードをサーバーに保持できます。詳細はComposition Patternsのページを参照してください。