客户端组件
客户端组件允许您编写在服务器上预渲染的 交互式 UI 并且可以使用客户端 JavaScript 在浏览器中运行。
本页将介绍客户端组件的工作原理、如何渲染以及何时使用它们。
客户端渲染的好处
在客户端进行渲染工作有几个好处,包括:
- 交互性: 客户端组件可以使用 state, effects 和事件监听器,这意味着它们可以向用户提供即时反馈并更新 UI。
- 浏览器 APIs: 客户端组件可以访问浏览器 API, 例如 geolocation 或 localStorage。
在 Next.js 中使用客户端组件
要使用客户端组件,您可以在文件顶部且 import 内容之上添加"use client" 指令。
"use client"用于声明服务器和客户端组件模块之间的 边界。这意味着,通过在文件中定义 "use client", 导入到其中的所有其他模块(包括子组件)都被视为客户端 bundle 的一部分。
"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 ')中如果没有定义' use client '指令,则使用onClick和useState将会导致错误。这是因为默认情况下,App Router 中的所有组件都是服务器组件,在这里这些 API 不可用。通过在toggle.js中定义"use client"指令, 您能够通知 React 进入了可以使用这些 API 的客户端边界。
定义多个
use client入口点:您可以在 React 组件树中定义多个"use client" 入口点。这样您就可以将应用程序拆分为多个客户端 bundles。
不过,
"use client"不需要在每个需要在客户端渲染的组件中定义。一旦定义了边界,导入其中的所有子组件和模块都被视为客户端 bundle 的一部分。
客户端组件如何渲染?
在 Next.js 中,客户端组件的渲染方式取决于请求是完整页面加载的一部分(对应用程序的首次访问或由浏览器刷新触发的页面重新加载)还是后续导航。
整页加载
为了优化初始页面加载,Next.js 将使用 React 的 API 在服务器端为客户端和服务器端组件渲染静态 HTML 预览。这意味着,当用户第一次访问您的应用程序时,他们将立即看到页面的内容,而不必等待客户端下载、解析和执行客户端组件 JavaScript bundle。
在服务器上:
- React 将服务器组件渲染为一种称为 React Server Component Payload (RSC Payload)的特殊数据格式,其中包含对客户端组件的引用。
- Next.js 使用 RSC Payload 和客户端组件 JavaScript 指令在服务器上为路由渲染 HTML。
然后, 在客户端:
- HTML 用于立即显示路由的快速非交互式初始预览。
- React 服务器组件 Payload 用于协调客户端和服务器组件树,并更新 DOM。
- JavaScript 指令用于hydrate 客户端组件并使其 UI 具有交互性。
什么是 hydration?
Hydration 是将事件监听器附加到 DOM 的过程,以使静态 HTML 具有交互性。在后台,hydration 是通过
hydrateRootReact API 完成的.
后续导航
在后续导航中,客户端组件完全在客户端上渲染,而无需服务器 渲染 HTML。
这意味着下载并解析客户端组件 JavaScript 包。一旦包准备就绪,React 将使用RSC Payload协调客户端和服务器组件树,并更新 DOM。
回到服务器环境
有时, 在您声明"use client"边界后, 您可能想要返回到服务器环境。例如,您可能想要减小客户端包大小、在服务器上获取数据或使用仅在服务器上可用的 API。
您可以将代码保存在服务器上即使理论上它是通过嵌套在客户端的。参阅Composition Patterns页面获取更多信息。
尽管理论上代码是嵌套在客户端组件中,但您可以通过交错客户端和服务器组件以及服务器操作将代码保存在服务器上。参阅Composition Patterns页面获取更多信息。