10
章节10
服务端和客户端组件
要理解服务端和客户端组件的工作原理,熟悉以下两个基本的 Web 概念会很有帮助:
服务端和客户端环境
在 Web 应用程序的上下文中:

- 客户端指的是用户设备上的浏览器,它向服务器发送请求以获取你的应用程序代码。然后,它将从服务器接收到的响应转换为用户可以交互的界面。
- 服务端指的是数据中心中的计算机,它存储你的应用程序代码,接收来自客户端的请求,执行一些计算,并发送回适当的响应。
每个环境都有自己的一组功能和约束。例如,通过将渲染和数据获取移至服务器,你可以减少发送到客户端的代码量,从而提高应用程序的性能。但是,正如你之前了解到的,为了使你的 UI 具有交互性,你需要更新客户端上的 DOM。
因此,你为服务端和客户端编写的代码并不总是相同的。某些操作(例如,数据获取或管理用户状态)更适合在某个环境中执行。
网络边界
网络边界是一条概念性的线,它分隔了不同的环境。
在 React 中,你可以选择将网络边界放置在组件树中的位置。例如,你可以在服务端获取数据并渲染用户的帖子(使用服务端组件),然后在客户端上为每个帖子渲染交互式的 LikeButton
(使用客户端组件)。
类似地,你可以创建一个在服务端渲染并在页面之间共享的 Nav
组件,但是如果你想显示链接的活动状态,你可以在客户端上渲染 Links
列表。

在幕后,组件被拆分为两个模块图。服务端模块图(或树)包含所有在服务端渲染的服务端组件,而客户端模块图(或树)包含所有客户端组件。
在服务端组件渲染完成后,一种称为 React 服务端组件有效负载 (RSC) 的特殊数据格式被发送到客户端。RSC 有效负载包含:
- 服务端组件的渲染结果。
- 客户端组件应渲染位置的占位符(或空位)以及对其 JavaScript 文件的引用。
React 使用此信息来整合服务端和客户端组件,并更新客户端上的 DOM。
让我们看看这是如何工作的。
使用客户端组件
正如你在上一章中学到的,Next.js 默认使用服务端组件 - 这是为了提高应用程序的性能,意味着你无需采取额外的步骤来采用它们。
回顾浏览器中的错误,Next.js 警告你正在尝试在服务端组件内部使用 useState
。你可以通过将交互式的“点赞”按钮移动到客户端组件来修复此问题。
在 app
文件夹内创建一个名为 like-button.js
的新文件,该文件导出一个 LikeButton
组件
export default function LikeButton() {}
将 <button>
元素和 handleClick()
函数从 page.js
移动到你的新 LikeButton
组件
export default function LikeButton() {
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
接下来,移动 likes
状态和导入
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
现在,要使 LikeButton
成为客户端组件,请在文件顶部添加 React 'use client'
指令。这告诉 React 在客户端上渲染该组件。
'use client';
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
回到你的 page.js
文件,将 LikeButton
组件导入到你的页面中
import LikeButton from './like-button';
function Header({ title }) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<LikeButton />
</div>
);
}
保存这两个文件并在浏览器中查看你的应用程序。现在没有错误了,一旦你进行更改并保存,你应该会注意到浏览器自动更新以反映更改。
此功能称为 快速刷新。它可以让你即时反馈你所做的任何编辑,并且已预先配置在 Next.js 中。
总结
回顾一下,你了解了服务端和客户端环境以及何时使用每个环境。你还了解到 Next.js 默认使用 React 服务端组件来提高性能,以及如何选择客户端组件来使你的 UI 的较小部分具有交互性。
拓展阅读
关于服务端和客户端组件,还有很多内容可以学习。以下是一些额外的资源:
这是否有帮助?