服务端和客户端组件

Next.js App Router 下,组件默认都是 React Server Component(RSC,服务端组件),它们只在服务端运行,不携带 JS 到浏览器。如果组件需要 useState、useEffect、浏览器 API 或事件处理,就要在文件顶部加 "use client",使它成为 Client Component(客户端组件)。

来源整理自:vue3js.cn 面试官系列

关键差异

维度Server Component(RSC)Client Component
运行环境仅服务端服务端 + 浏览器
是否打包进 JS bundle否是
支持 React Hooks否是
可访问 window/localStorage否是
可直接查询数据库 / 文件系统是否
默认渲染方式App Router 默认为 RSC需 "use client" 显式声明

补充

补充:哪些文件 / 钩子必须是 Client Component。

  • error.js / global-error.js / not-found.js:由于需要接收 error 参数并触发刷新,框架约定为客户端组件,会自动加上 "use client"。
  • loading.js、layout.js(默认服务端组件):可在内部使用 <Suspense fallback> 包裹子节点,但本身不要求客户端化。
  • 使用 useState / useEffect / 事件回调(onClick 等) / 浏览器 API(window、document)的组件,必须声明为客户端组件。
  • 注意:客户端组件不能直接 await 服务端组件;但服务端组件可以渲染客户端组件,且会把客户端组件标记为 RSC payload 的一部分。
// app/counter/page.tsx
"use client";

import { useState } from "react";

export default function Counter() {
  const [n, setN] = useState(0);
  return <button onClick={() => setN(n + 1)}>{n}</button>;
}