客戶端元件 (Client Components)

客戶端元件 (Client Components) 讓您能撰寫互動式 UI,這些 UI 會在伺服器預先渲染,並可使用客戶端 JavaScript 在瀏覽器中執行。

本頁將介紹客戶端元件 (Client Components) 的運作原理、渲染方式以及適用情境。

客戶端渲染的優勢

在客戶端進行渲染工作有幾個優勢,包括:

  • 互動性:客戶端元件 (Client Components) 可使用狀態 (state)、副作用 (effects) 和事件監聽器 (event listeners),意味著能提供使用者即時回饋並更新 UI。
  • 瀏覽器 API:客戶端元件 (Client Components) 能存取瀏覽器 API,例如地理位置 (geolocation)localStorage

在 Next.js 中使用客戶端元件 (Client Components)

要使用客戶端元件 (Client Components),您可以在檔案頂部、import 語句之前加入 React 的 "use client" 指令

"use client" 用於宣告伺服器元件 (Server Components) 和客戶端元件 (Client Components) 模組之間的邊界 (boundary)。這表示在檔案中定義 "use 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" 指令,在嵌套元件 (toggle.js) 中使用 onClickuseState 會導致錯誤。這是因為在 App Router 中,預設所有元件都是伺服器元件 (Server Components),這些 API 不可用。在 toggle.js 中定義 "use client" 指令後,就能告訴 React 進入客戶端邊界,這些 API 便可使用。

Use Client Directive and Network Boundary

定義多個 use client 進入點

您可以在 React 元件樹中定義多個 "use client" 進入點。這讓您能將應用程式拆分為多個客戶端套件。

但並非每個需要在客戶端渲染的元件都需定義 "use client"。一旦定義邊界後,所有子元件和導入的模組都會被視為客戶端套件的一部分。

客戶端元件 (Client Components) 如何渲染?

在 Next.js 中,客戶端元件 (Client Components) 的渲染方式會根據請求是屬於完整頁面載入(首次訪問應用程式或由瀏覽器刷新觸發的頁面重新載入)還是後續導航而有所不同。

完整頁面載入

為了優化初始頁面載入,Next.js 會使用 React 的 API 在伺服器上為客戶端元件 (Client Components) 和伺服器元件 (Server Components) 渲染靜態 HTML 預覽。這表示使用者首次訪問您的應用程式時,會立即看到頁面內容,無需等待客戶端下載、解析和執行客戶端元件 (Client Components) 的 JavaScript 套件。

在伺服器上:

  1. React 將伺服器元件 (Server Components) 渲染為一種特殊資料格式,稱為 React 伺服器元件負載 (RSC Payload),其中包含對客戶端元件 (Client Components) 的引用。
  2. Next.js 使用 RSC Payload 和客戶端元件 (Client Components) 的 JavaScript 指令在伺服器上渲染路由的 HTML

然後,在客戶端:

  1. 使用 HTML 立即顯示路由的非互動式快速初始預覽。
  2. 使用 React 伺服器元件負載 (RSC Payload) 協調客戶端元件 (Client Components) 和伺服器元件 (Server Components) 樹,並更新 DOM。
  3. 使用 JavaScript 指令水合 (hydrate) 客戶端元件 (Client Components),使其 UI 具有互動性。

什麼是水合 (hydration)?

水合 (hydration) 是將事件監聽器附加到 DOM 的過程,使靜態 HTML 具有互動性。在底層,水合 (hydration) 是透過 React 的 hydrateRoot API 完成的。

後續導航

在後續導航中,客戶端元件 (Client Components) 完全在客戶端渲染,無需伺服器渲染的 HTML。

這表示客戶端元件 (Client Components) 的 JavaScript 套件會被下載和解析。一旦套件準備就緒,React 會使用 RSC Payload 協調客戶端元件 (Client Components) 和伺服器元件 (Server Components) 樹,並更新 DOM。

返回伺服器環境

有時,在宣告 "use client" 邊界後,您可能需要返回伺服器環境。例如,您可能希望減少客戶端套件大小、在伺服器上獲取資料,或使用僅在伺服器上可用的 API。

您可以透過交錯使用客戶端元件 (Client Components) 和伺服器元件 (Server Components) 以及伺服器操作 (Server Actions),將程式碼保留在伺服器上,即使理論上它嵌套在客戶端元件 (Client Components) 中。詳情請參閱組合模式 (Composition Patterns) 頁面。

On this page