ReReact 服务器组件 (Server Components, RSC)与客户端组件的区别?
React 服务器组件(React Server Components,简称 RSC)是 React 18 引入的一项新特性,旨在提升 Web 应用的性能与可扩展性。它与传统的客户端组件(Client Components)在设计理念、运行环境、功能支持等方面有显著区别。以下是它们之间的主要区别:
一、定义与运行位置
| 类别 | React 服务器组件 (RSC) | 客户端组件 (Client Components) |
|---|---|---|
| 执行环境 | 在服务端运行(Node.js / Edge Runtime) | 在浏览器中运行(通过 JavaScript bundle) |
| HTML/JSX输出 | 仅返回渲染后的 UI(不含 JS),或序列化的 RSC Payload | 返回包含交互逻辑的完整 JS Bundle |
| JS Bundle大小影响 | ❌不会增加前端 JS bundle体积 ✅有助于减小 bundle | ✅会增大前端 JS bundle体积 |
二、功能支持差异
| 功能点 | RSC(服务器组件) | Client Components |
|---|---|---|
| useState / useEffect / useReducer等 Hooks | ❌不支持(服务端无状态交互能力) | ✅完全支持 |
| Event Handlers (onClick, onChange等) | ❌不支持事件处理直接在组件中写逻辑,需借助客户端子组件实现交互性 | ✅支持所有事件处理机制 |
| Browser-only API访问(如 localStorage, window, navigator等) | ❌不可使用,因不在浏览器中执行 | ✅可以使用 |
| Data Fetching(数据请求)优化能力更强:可直接访问数据库/文件系统等资源,无需额外API层封装;适合静态生成和SSR场景。例如直接调用 ORM/fetch from DB. | ||
| ✅推荐用于数据获取逻辑放在离数据源最近的位置,减少网络开销。 | ||
| ⚠️注意:不能直接传递函数给子组件作为 props。 | ||
| ✨优势:避免将敏感信息打包进前端bundle中。 | ||
| ✨缺点:不能缓存响应到 CDN?视具体框架而定。 | ||
| ✨适用于 SSR/SSG/ISR等场景。 | ||
| ❗️注意:RSC的fetch默认会被缓存策略控制,比如Next.js中的默认行为可能不同。 |
三、使用方式及语法约定
React Server Component:
- Next.js App Router中默认所有组件都是 RSC;
- “use client”指令用于显式声明为客户端组件;
- RSC中可以导入其他 RSC,也可以嵌套 Client Component;
- RSC无法接收来自客户端的 props中包含函数类型的值。
Client Component:
- 必须添加 "use client" directive;
- 可以拥有自己的 state、effect、事件监听器等;
- 可嵌套其他 Client/RSC;但只能从上层接收普通的数据 props。
四、典型应用场景对比
🟢 React Server Components适用场景:
- 📦展示型页面内容为主;
- 🔍需要频繁拉取后端数据且对安全性要求高;
- 🧼希望减少前端 JavaScript bundle大小;
- 🛠️构建高性能 SSR/SSG/ISR页面;
- 💾直接访问数据库或文件系统读取内容;
🔵 Client Components适用场景:
- 🎯页面中包含大量用户交互逻辑(表单输入、动画等);
- 👂需要监听浏览器事件或使用生命周期钩子;
- ☁️需要使用第三方库依赖 DOM/BOM API (如图表库 ECharts, D3);
- 🧩实现复杂状态管理或动态 UI;
五、总结表格
| Feature | Server Component | Client Component |
|---|---|---|
| Runs on | Server | Browser |
| Access to backend resources directly? | ✅ Yes | ❌ No |
| Can use hooks like useState? | ❌ No | ✅ Yes |
| Can handle events (onClick)? | ❌ No | ✅ Yes |
| Adds to JS bundle size | ❌ No | ✅ Yes |
| Use browser APIs (window/localStorage)? | ❌ No | ✅ Yes |
六、最佳实践建议
- 【优先使用 Server Component】:尽量将数据获取和静态内容渲染放在服务器端完成。
- 【合理使用 Client Component】:只在需要交互性或浏览器 API时才标记为"use client"。
- 【组合使用】:Server Component负责“说什么”,Client Component负责“做什么”。
- 【避免传递函数props跨边界】:RSC不能向Client传递函数类型 prop。
七、参考示例(以 Next.js App Router为例)
// app/page.tsx — Server component by default
export default function Home() {
const data = await fetchDataFromDB(); // Direct access!
return (
Welcome
// components/Counter.tsx — Marked as client component!
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count};
}
结语:
React Server Components代表了 React「服务端驱动+轻量客户端」的未来趋势,它让开发者能更高效地构建兼具性能与体验的现代 Web应用。而理解并合理区分和使用 Server vs Client Components是掌握新一代 React/Next.js架构的关键所在。