AI AgentTechnical Deep Dive
React Server Components 原理与应用 —— 前后端融合新范式
发布时间2026/03/29
分类AI Agent
预计阅读2 分钟
作者吴长龙
*
什么是 React Server Components?
01.内容
什么是 React Server Components?
React Server Components(RSC)是 React 18 引入的重大特性,它允许组件在服务端运行,只将渲染结果发送到客户端。
核心概念
#### 服务端组件 vs 客户端组件
jsx snippetjsx
// Server Component(默认)- 在服务端运行
async function ServerComponent() {
const data = await db.query('SELECT * FROM posts');
// 可以直接访问数据库、文件系统
return (
<ul>
{data.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
// 客户端组件 - 在浏览器运行
'use client';
function ClientComponent() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}#### 关键特性
| 特性 | 服务端组件 | 客户端组件 |
|---|---|---|
| 运行位置 | 服务端 | 浏览器/客户端 |
| 直接访问数据库 | ✅ | ❌ |
| 使用 useState/Effect | ❌ | ✅ |
| 交互事件 | ❌ | ✅ |
| 打包到 bundle | ❌ | ✅ |
| 可以是 async | ✅ | ❌ |
工作原理
#### 1. 流式 SSR + 选择性水合
传统 SSR:整页渲染完成后才开始 hydration
RSC 方式:
code snippetcode
服务端:组件树 → 序列化 → 流式输出
↓
客户端:逐步接收 → 选择性 hydration#### 2. Server Action
服务端组件可以定义"服务端 action",客户端调用:
jsx snippetjsx
// Server Component
async function AddPost() {
async function createPost(formData) {
'use server'; // 标记为服务端执行
await db.posts.create({
title: formData.get('title')
});
revalidatePath('/posts');
}
return (
<form action={createPost}>
<input name="title" />
<button type="submit">提交</button>
</form>
);
}#### 3. 数据获取模式
jsx snippetjsx
// 服务端组件中直接获取数据
async function PostList() {
const posts = await fetchPosts(); // 服务端执行,无额外 API
return (
<ul>
{posts.map(post => (
<PostItem key={post.id} post={post} />
))}
</ul>
);
}
// 客户端组件通过 server action 或 props 接收数据
'use client';
function PostItem({ post }) {
return <li>{post.title}</li>;
}实际应用场景
#### 1. 数据密集型页面
jsx snippetjsx
// 不需要 API 层,直接在服务端获取
async function Dashboard() {
const users = await db.users.count();
const orders = await db.orders.count();
const revenue = await db.orders.sum('amount');
return (
<div>
<Stat name="用户" value={users} />
<Stat name="订单" value={orders} />
<Stat name="收入" value={revenue} />
</div>
);
}#### 2. 保护敏感逻辑
jsx snippetjsx
// 服务端组件访问环境变量,不会泄露到客户端
async function APIKeyDisplay() {
const apiKey = process.env.SECRET_KEY; // 仅服务端可见
// 处理逻辑...
return null;
}#### 3. 大型列表优化
jsx snippetjsx
// 服务端渲染列表,客户端只 hydration 交互部分
async function ArticleList() {
const articles = await db.articles.findMany();
return (
<div>
{articles.map(article => (
<ArticleCard
key={article.id}
article={article}
// 客户端组件处理交互
actions={<ArticleActions id={article.id} />}
/>
))}
</div>
);
}Next.js App Router 中的 RSC
Next.js 13+ 默认使用 App Router,组件默认是服务端组件:
jsx snippetjsx
// app/posts/page.tsx
export default async function PostsPage() {
const posts = await getPosts();
return (
<main>
{posts.map(post => (
<PostCard key={post.id} post={post} />
))}
<NewPostForm /> {/* 客户端组件 */}
</main>
);
}
// app/posts/NewPostForm.tsx
'use client';
export function NewPostForm() {
// 交互逻辑...
}常见陷阱
#### 1. 混淆服务端/客户端组件
jsx snippetjsx
// 错误:服务端组件不能使用 useState
async function BadComponent() {
const [count, setCount] = useState(0); // ❌
return <div>{count}</div>;
}
// 正确:客户端组件需要 'use client'
'use client';
function GoodComponent() {
const [count, setCount] = useState(0);
return <div>{count}</div>;
}#### 2. 服务端组件中使用 window/document
jsx snippetjsx
// 错误:服务端没有 window
async function BadComponent() {
const width = window.innerWidth; // ❌
return <div>{width}</div>;
}#### 3. 过度使用服务端组件
jsx snippetjsx
// 如果需要大量交互,还是用客户端组件
'use client';
function InteractiveChart() {
// 图表交互逻辑...
}性能影响
| 指标 | 传统 SSR | RSC |
|---|---|---|
| 首屏时间 | 依赖 JS 加载 | 更快(流式) |
| Bundle 大小 | 全量 JS | 仅客户端 JS |
| 水合成本 | 全量 hydration | 选择性 hydration |
| 数据获取 | 客户端请求 | 服务端直连 |
总结
RSC 代表了 React 的未来方向:
- •更少的 JavaScript:只发送必要的客户端代码
- •更好的首屏性能:流式渲染 + 选择性 hydration
- •更简单的数据获取:直接访问后端资源
- •更清晰的架构:服务端/客户端职责分离
掌握 RSC,是 React 开发者必须面对的进阶之路。