Client Components
Client Components は、client で request 時間にレンダリングできる対話型 UI を書くことを可能にします。Next.js では、client レンダリングは任意参加で、つまり何の Component が React によって client 上で render されるべきかを明示的に決定する必要があります。
このページでは、Client Components の動作方法、レンダリングの仕方、そしてそれらをいつ使用するかについて説明します。
Benefits of Client Rendering
client でレンダリング作業を行うことにはいくつかの利点があります。これには以下のようなものがあります:
- 対話性: Client Components は状態、エフェクト、イベントリスナーを使用でき、これによりユーザーに対して即座のフィードバックを提供し、UI を更新することができます。
- ブラウザ API: Client Components は、ジオロケーション やローカルストレージ などのブラウザ API にアクセスでき、特定のユースケースのための UI を build できます。
Using Client Components in Next.js
Client Components を使用するには、インポートの上にあるファイルの先頭に React "use client"
directive を追加できます。
"use client"
は Server と Client Component modules 間の境界を宣言するために使用されます。これは、ファイルに "use client"
を定義することで、それにインポートされた他のすべての modules、子 components を含む、client バンドルの一部と見なされることを意味します。
'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>
)
}
以下の図は、ネストされた component(toggle.js
) でonClick
とuseState
を使用すると、"use client"
ディレクティブが定義されていない場合、「error」が発生することを示しています。これは、default では、component が「サーバ」上で rendering され、これらの API が利用できないからです。toggle.js
内に"use client"
ディレクティブを定義することで、「React」に「client」上で「component」とその「子」を「rendering」するよう指示することができ、そこでは API が利用可能です。
複数の
use client
エントリーポイントを定義する:あなたは React Component ツリー内で複数の"use client"エントリーポイントを定義することができます。これにより、アプリケーションを複数の client バンドル(またはブランチ)に分割することができます。
ただし、
"use client"
は、 client 上でレンダリングする必要があるすべての component で定義する必要はありません。一度境界を定義すると、それにインポートされたすべての子コンポーネントと modules は、 client バンドルの一部と見なされます。
How are Client Components Rendered?
Next.js では、request が全ページのロード(初回訪問やブラウザの refresh によるページ再読み込み)の一部かどうかにより、Client Components が異なる形でレンダリングされます。これは後続のナビゲーションの場合も同じです。
フルページのロード
初期ページのロードを最適化するために、Next.js は、React の API を使用して、Client および Server Components の両方に対して、静的な HTML preview を server 上で render します。これは、ユーザーが最初にアプリケーションを訪れたときに、client が Client Component JavaScript バンドルをダウンロード、解析、実行するのを待つことなく、すぐにページの内容を表示できることを意味します。
server 上で:
- React は、**React Server Component Payload (RSC Payload)**と呼ばれる特別なデータ形式に、Server Components をレンダリングします。これには Client Components への参照が含まれています。
- Next.js は RSC Payload と Client Component JavaScript の指示を使用して、server 上の route に対するHTMLを render します。
次に、クライアントで:
- HTML は、すぐに高速で非対話的な最初の preview を route の表示するために使用されます。
- React Server Components Payload は、Client と Server Component のツリーを調整し、DOM を更新するために使用されます。
- JavaScript の指示は、hydrate するために使われ、Client Components を活性化させ、その UI をインタラクティブにします。
ハイドレーションとは何ですか?
Hydration は、静的な HTML をインタラクティブにするために、イベントリスナーを DOM にアタッチするプロセスです。裏側では、hydration は
hydrateRoot
React API を使用して行われます。
その後のナビゲーション
次回のナビゲーション以降では、Client Components はすべて client 上でレンダリングされ、server レンダリングの HTML なしで表示されます。
これは、Client Component JavaScript バンドルがダウンロードされ、解析されることを意味します。バンドルが準備完了したら、React は RSC Payload を利用して、Client と Server Component のツリーを調整し、DOM を更新します。
Going back to the Server Environment
時々、"use client"
の境界を宣言した後で、server の環境に戻りたい場合があります。例えば、client バンドルの size を減らしたい、server 上でデータを fetch したい、または server 上でのみ利用可能な API を使用したい場合などです。
理論的には Client Components の中にネストしているとしても、Client と Server Components を交互に配置することにより、code を server に保持することができます。詳細については、Composition PatternsページとServer Actionsをご覧ください。