返回首页
⚙️技术札记
#React#RSC#Next.js#前端架构#应用开发

React Server Components 的思考与实践

4 分钟阅读有封面图
React Server Components 的思考与实践

一、缘起:为什么需要 Server Components?#

2020 年底,React 团队在 RFC 中首次提出了 Server Components 的概念。 当时社区一片哗然——"React 不是客户端框架吗?服务端渲染(SSR)不是已经有 Next.js 做了吗?"

答案藏在两个核心痛点里:

  1. 瀑布式数据请求。 传统的 CSR 应用中,组件树渲染 → 发现数据依赖 → 发起请求 → 等待响应,层层递进,像多米诺骨牌一样依次倒下。
  2. 客户端 JS 体积膨胀。 日期格式化库、Markdown 解析器、语法高亮…… 这些"纯函数"般的依赖占据了最终 bundle 的 40% 以上,但它们本就不需要 在浏览器里运行

二、核心心智模型#

RSC 的精髓在于一个简单的二元划分:

类型 运行环境 能力
Server Component(默认) 服务端 直接访问数据库/文件系统、import 重型库、Node.js API
Client Component 浏览器 useState、useEffect、事件处理、浏览器 API
// ✅ server-component.tsx —— 默认就是服务端组件
import { db } from "@/lib/db";

export default async function PostList() {
  const posts = await db.post.findMany();  // 直接查数据库,零客户端 JS!
  return (
    <ul>
      {posts.map(p => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}
// ✅ client-component.tsx —— 'use client' 边界标记
'use client';

import { useState } from 'react';

export default function LikeButton({ postId }: { postId: string }) {
  const [liked, setLiked] = useState(false);
  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? '❤️' : '🤍'}
    </button>
  );
}

三、实践中的三个关键决策#

1. 服务端组件 vs 客户端组件的边界在哪里?#

我的原则:叶子节点优先客户端,数据流优先服务端。

  • 列表容器 → 服务端(数据获取)
  • 列表项交互按钮 → 客户端(事件处理)
  • 评论区展示 → 服务端(首屏渲染)
  • 评论输入框 → 客户端(表单交互)

2. 如何优雅地传递数据?#

避免 prop drilling 的最佳实践:在服务端组件中完成所有数据获取, 通过 props 向下传递给客户端组件。服务端组件可以嵌套客户端组件, 但反过来不行——'use client' 是单向边界

3. 第三方库的兼容性#

大部分 UI 库(如 Radix UI、Headless UI)已经全面支持 RSC。 对于尚未适配的库(如某些图表库),使用 dynamic(() => import(...), { ssr: false }) 包裹即可。

四、总结#

RSC 不是对现有模式的推翻,而是补充。它让 React 从"一刀切的客户端渲染" 进化为"在组件粒度上自由选择运行时"。这是一种对开发者友好的渐进式变革—— 你可以从一个组件开始,逐步将数据获取逻辑迁移到服务端,而不需要重写整个应用。

最好的架构,是让正确的代码运行在正确的地方。

感谢阅读。如果这篇文章对你有所启发,那便是写作最大的意义。
— 黑豆拾光录