8 分钟

深入理解 React Server Components

Server Components 改变了我们构建 React 应用的方式。组件默认在服务端运行,零客户端 JS 开销,数据获取更直接。本文带你从原理到实践,全面掌握这一范式转变。

深入理解 React Server Components

什么是 Server Components?

React Server Components(RSC)是 React 架构的一次根本性演进。与传统的客户端组件不同,Server Components 完全在服务器上执行,它们的代码永远不会被发送到浏览器。

这意味着你可以自由地: - 直接访问数据库、文件系统 - 使用服务端专属的库(如 Node.js 原生模块) - 将敏感逻辑(密钥、鉴权)保留在服务端

为什么需要 Server Components?

传统的 React 应用存在一个根本问题:所有组件代码都会被发送到客户端。即使一个组件只是展示从 API 获取的静态数据,它的渲染逻辑、依赖库都会打包进客户端 bundle。

// 这是一个 Server Component(默认行为)
// 它的代码不会出现在客户端 bundle 中
async function BlogPost({ id }: { id: string }) {
  const post = await db.post.findUnique({ where: { id } });
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

注意这里可以直接 await 一个数据库查询——没有 useEffect,没有 loading 状态,没有 API 路由中间层。

Server vs Client Components

在 Next.js App Router 中:

特性Server ComponentClient Component
默认行为✅ 是需要 `"use client"`
访问数据库✅ 可以❌ 不行
使用 hooks❌ 不行✅ 可以
事件处理❌ 不行✅ 可以
打包大小影响增加 bundle

关键原则:尽可能使用 Server Components,只在需要交互时使用 Client Components。

组合模式

Server Components 和 Client Components 可以灵活组合。一个常见模式是将数据获取放在 Server Component 中,将交互逻辑封装在 Client Component 中:

// Server Component:获取数据
async function CommentSection({ postId }: { postId: string }) {
  const comments = await db.comment.findMany({ where: { postId } });
  // 将数据传递给 Client Component
  return <CommentList initialComments={comments} />;

// Client Component:处理交互 "use client"; function CommentList({ initialComments }) { const [comments, setComments] = useState(initialComments); // 处理添加、删除评论等交互... } ```

流式渲染与 Suspense

Server Components 天然支持流式渲染。配合 React Suspense,可以让页面的不同部分独立加载:

export default function Page() {
  return (
    <main>
      <h1>文章详情</h1>
      {/* 文章内容先到先展示 */}
      <Suspense fallback={<ArticleSkeleton />}>
        <ArticleContent />
      </Suspense>
      {/* 评论区独立加载,不阻塞文章 */}
      <Suspense fallback={<CommentsSkeleton />}>
        <Comments />
      </Suspense>
    </main>
  );
}

总结

Server Components 不是对现有模式的替代,而是一种互补。它们让我们能够根据每个组件的实际需求,选择最合适的渲染策略。在 Next.js 中,这一切都是开箱即用的——App Router 让 Server Components 成为了默认选择,你只需要专注于构建产品。