客户端组件 (Client Components)
客户端组件 (Client Components) 允许您编写交互式用户界面,这些界面会在服务端预渲染,并能在浏览器中使用客户端 JavaScript 运行。
本页将介绍客户端组件 (Client Components) 的工作原理、渲染方式以及适用场景。
客户端渲染的优势
在客户端执行渲染工作具有以下优势:
- 交互性:客户端组件 (Client Components) 可以使用状态 (state)、副作用 (effects) 和事件监听器 (event listeners),意味着它们能立即响应用户操作并更新界面。
- 浏览器 API:客户端组件 (Client Components) 能够访问浏览器 API,例如地理位置定位或本地存储。
在 Next.js 中使用客户端组件
要使用客户端组件 (Client Components),您可以在文件顶部、导入语句之前添加 React 的 "use client"
指令。
"use client"
用于声明服务端组件 (Server Components) 和客户端组件 (Client Components) 模块之间的边界。这意味着通过在文件中定义 "use client"
,所有导入该文件的模块(包括子组件)都将被视为客户端包的一部分。
下图展示了在嵌套组件 (toggle.js
) 中使用 onClick
和 useState
时,如果未定义 "use client"
指令会导致错误。这是因为在应用路由 (App Router) 中,默认所有组件都是服务端组件 (Server Components),这些 API 不可用。通过在 toggle.js
中定义 "use client"
指令,您可以告知 React 进入这些 API 可用的客户端边界。

定义多个
use client
入口点:您可以在 React 组件树中定义多个 "use client" 入口点。这允许您将应用拆分为多个客户端包。
但并非每个需要在客户端渲染的组件都需要定义
"use client"
。一旦定义了边界,所有子组件和导入的模块都将被视为客户端包的一部分。
客户端组件如何渲染?
在 Next.js 中,客户端组件 (Client Components) 的渲染方式取决于请求是完整页面加载(首次访问应用或浏览器刷新触发的页面重载)还是后续导航。
完整页面加载
为了优化初始页面加载,Next.js 会使用 React 的 API 在服务端为客户端组件 (Client Components) 和服务端组件 (Server Components) 渲染静态 HTML 预览。这意味着用户首次访问您的应用时,会立即看到页面内容,而无需等待客户端下载、解析和执行客户端组件 (Client Components) 的 JavaScript 包。
在服务端:
- React 将服务端组件 (Server Components) 渲染为一种特殊数据格式——React 服务端组件负载 (RSC Payload),其中包含对客户端组件 (Client Components) 的引用。
- Next.js 使用 RSC Payload 和客户端组件 (Client Components) 的 JavaScript 指令在服务端渲染路由的 HTML。
然后在客户端:
- 使用 HTML 立即显示路由的快速非交互式初始预览。
- 使用 React 服务端组件负载 (RSC Payload) 协调客户端组件 (Client Components) 和服务端组件 (Server Components) 的组件树,并更新 DOM。
- 使用 JavaScript 指令对客户端组件 (Client Components) 进行水合 (hydrate),使其界面可交互。
什么是水合 (hydration)?
水合 (hydration) 是将事件监听器附加到 DOM 的过程,使静态 HTML 具有交互性。在底层,水合是通过 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) 内部。更多信息请参阅组合模式页面。