缩小客户端部分
本课属于 Coddy React 学习旅程的“Next.js 基础”单元。第 20 课,共 47 课。
当页面只需要一个交互式按钮时,有个很诱人的捷径:在页面顶部加上 'use client',然后继续开发。这样确实能用,但这也是最常见的做法,会让你白白丢掉 Next.js 刚刚带给你的一切。
记住规则 2:指令会标记整个文件。页面、标题、描述、菜品列表,以及它们渲染的所有组件都会变成客户端代码,并在浏览器中下载和重新运行。一个按钮就把整个页面拖到了边界的另一侧。
解决这个问题的习惯很简单,而且只需机械地执行:
将
'use client'尽量下移到叶子节点。
把交互部分拆分到一个单独的小文件中,标记这个文件,并让页面继续留在服务器端:
// app/page.jsx 仍是服务器组件
import LikeButton from '../components/LikeButton';
export default function Home() {
return (
<main>
<h1>Coddy Eats</h1>
<LikeButton />
</main>
);
}有两点需要注意。首先,服务器组件可以渲染客户端组件,这种方式完全正常。其次,页面的结构没有变化,只有一个小部分移动了。
还有一个错误会让你养成同样的习惯。直接在服务器组件中的按钮上添加 onClick,运行时就会阻止你:事件处理函数不能传递给客户端组件的属性。事件处理函数是一个函数:除非它位于客户端文件中,否则无法在传到浏览器的过程中保留下来。
挑战
简单这个页面在服务器组件内部的按钮上添加了 onClick,因此应用完全无法渲染。
修复这个问题,不要将页面标记为客户端组件:
- 在
components/LikeButton.jsx中编写一个客户端组件(第 1 行写上'use client'),用状态保存点赞数,并渲染一个带有id="like"的按钮。按钮文本必须是Likes:,后面接点赞数。 - 在
app/page.jsx中,删除有问题的按钮,改为渲染<LikeButton />。从'../components/LikeButton'导入它。 - 标题和标语保持原样:页面必须继续作为服务器组件。
亲手试试
import './globals.css';
export const metadata = {
title: 'My App',
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。