React Server Components 指南:原理、实战与框架对比

by JeariCk 4 min read
react server components

2026年,React Server Components(简称RSC)不再是概念实验。State of React 2026的数据显示,超过50%的开发者想在生产环境用上它。但它到底是什么?跟传统SSR区别在哪?在Next.js之外怎么看?

这篇文章主要讲它是什么 → 怎么写代码 → 跟其他方案怎么比

react server components
react server components

第一部分:React Server Components是什么,解决了什么问题

问题的起点

传统的React应用是纯客户端渲染(CSR)。浏览器下载整个JS包,在客户端构建DOM树、获取数据、渲染界面。这个过程有几个痛点:

– 用户首屏要等JS下载→编译→执行→数据请求→渲染,链条很长

– 低端设备处理大JS包很吃力

– 大部分组件并没有交互需求(文章正文、列表项),但JS仍然要发到浏览器

为了解决这些问题,React引入了服务端渲染(SSR)。SSR的思路是在服务端把组件渲染成HTML再发给浏览器,让用户更快看到内容。但这只是「披了一层HTML的CSR」——浏览器仍然要下载完整的JS包并进行水合(Hydration),把静态HTML变成可交互的React应用。

React Server Components的切入点完全不同。RSC不是让所有组件都在服务端渲染,而是让部分组件只在服务端运行,完全不发送JS到浏览器。

RSC vs SSR vs CSR:本质区别

理解RSC的关键在于它和SSR是两个正交的概念:

/CSRSSRRSC
渲染位置浏览器服务端→浏览器服务端(部分组件)
JS是否发给浏览器全部全部(仍需水合)只发Client Component
数据获取客户端请求API服务端可预取直接访问数据库/FS
交互支持完整完整(水合后)不支持
包体积影响完整包完整包仅交互部分

RSC 的核心工作方式

RSC的渲染流程可以拆成几步:

1. 服务端收到请求,从根组件开始渲染。根组件必须是Server Component

2. 遇到 Server Component,正常执行,生成React元素树

3. 遇到 `’use client’` 标记的 Client Component,不执行内部逻辑,而是生成一个占位符加模块引用,交给浏览器后续处理

4. 服务端把渲染结果序列化成一种特殊格式(叫做Flight payload),流式发送到浏览器

5. 浏览器收到后,重建React树——Server Component部分直接用序列化后的结果,Client Component部分按模块引用下载JS并渲染

关键区别在于:Server Component的输出不是HTML,而是一个序列化的React元素树。这让React可以在客户端精确恢复组件结构,同时零成本地跳过不需要交互的部分。


第二部分:上代码

Server Component 基础

默认情况下,Next.js App Router中的所有组件都是Server Component。不需要额外声明:

```tsx

// app/posts/page.tsx — 这是一个 Server Component

import { db } from '@/lib/database'

export default async function PostsPage() {

  const posts = await db.post.findMany({ take: 20 })

  return (

    <div>

      <h1>最新文章</h1>

      {posts.map(post => (

        <article key={post.id}>

          <h2>{post.title}</h2>

          <p>{post.excerpt}</p>

        </article>

      ))}

    </div>

  )

}

```

这个组件:

– 在服务端执行,数据库查询zero round-trip

– 返回给浏览器的只有最终HTML

– 没有JS bundle——因为它没有任何交互

Client Component 标记

需要交互的时候,加 `’use client’`:

```tsx

// app/components/LikeButton.tsx

'use client'

import { useState } from 'react'

export default function LikeButton({ postId }: { postId: number }) {

  const [liked, setLiked] = useState(false)

  return (

    <button onClick={() => setLiked(!liked)}>

      {liked ? '❤️ 已赞' : '🤍 点赞'}

    </button>

  )

}

```

混用的正确姿势

Server Component不能直接import Client Component用来渲染——但可以通过children(组合模式)来嵌套。这是RSC架构中最核心的设计模式:

```tsx

// app/posts/page.tsx (Server Component)

import { db } from '@/lib/database'

import LikeButton from './LikeButton' // Client Component

export default async function PostsPage() {

  const posts = await db.post.findMany({ take: 20 })

  return (

    <div>

      {posts.map(post => (

        <PostCard key={post.id} post={post}>

          <LikeButton postId={post.id} />

        </PostCard>

      ))}

    </div>

  )

}

```

```tsx

// ❌ 错误:不能在 Client Component 中 import Server Component

'use client'

import ServerComponent from './ServerComponent' // 报错!

export default function ClientComponent() {

  return <ServerComponent />

}

```

```tsx

// ✅ 正确:通过 children 传递

'use client'

export default function ClientComponent({ children }: { children: React.ReactNode }) {

  return <div className="card">{children}</div>

}

```

数据获取在 Server Component 中

React Server Components最大的优势之一就是数据获取可以直接写进组件,不需要额外封装一套API:

```tsx

// Server Component — 直接查数据库,零客户端JS

export default async function UserDashboard({ userId }: { userId: string }) {

  const user = await db.user.findUnique({ where: { id: userId } })

  const posts = await db.post.findMany({ where: { authorId: userId } })

  return (

    <div>

      <h1>{user.name} 的仪表盘</h1>

      <p>共 {posts.length} 篇文章</p>

    </div>

  )

}

```

对比客户端方案——需要多一层API路由和状态管理:

```tsx

'use client'

import { useEffect, useState } from 'react'

export default function UserDashboard({ userId }: { userId: string }) {

  const [user, setUser] = useState(null)

  const [posts, setPosts] = useState([])

  useEffect(() => {

    fetch(`/api/users/${userId}`)

      .then(r => r.json())

      .then(data => {

        setUser(data.user)

        setPosts(data.posts)

      })

  }, [userId])

  if (!user) return <div>加载中...</div>

  return (

    <div>

      <h1>{user.name} 的仪表盘</h1>

      <p>共 {posts.length} 篇文章</p>

    </div>

  )

}

```

Server Actions:表单处理

React 19引入的Server Actions让表单提交可以直接调服务端函数:

```tsx

// app/actions.ts

'use server'

import { db } from '@/lib/database'

import { revalidatePath } from 'next/cache'

export async function createPost(formData: FormData) {

  const title = formData.get('title') as string

  const content = formData.get('content') as string

  await db.post.create({ data: { title, content } })

  revalidatePath('/posts')

}

```

```tsx

// app/posts/new/page.tsx — Server Component

import { createPost } from './actions'

export default function NewPostPage() {

  return (

    <form action={createPost}>

      <input name="title" placeholder="文章标题" required />

      <textarea name="content" placeholder="内容" />

      <button type="submit">发布</button>

    </form>

  )

}

```

不需要写API路由、不需要fetch。


第三部分:竞品对比

RSC不是唯一的「减少客户端JS」方案。

RSC vs Astro

核心思路差异

– RSC:在服务端渲染部分组件,保留完整的React交互能力

– Astro:默认零JS,按需加载部分交互组件(Islands架构),可以用React/Vue/Svelte等框架

选型建议

场景RSCAstro
内容型网站(博客/文档)可用更优
高交互应用(仪表盘/SaaS)更优需要额外工作
多框架团队仅React任意框架
需要完整React生态原生支持有限支持

Astro在内容型站点上更激进——默认不发送任何JS。一个纯展示的博客页面,Astro的输出只有HTML+CSS,零JS。而RSC在这个场景虽然也能做到零JS,但在Next.js框架层还是有一些runtime开销。

RSC vs Qwik

Qwik的核心思路是「可恢复性」——不发送交互代码,直到用户触发交互时才下载对应的JS片段。

区别在于:

– RSC:数据获取和渲染在服务端执行,Client Component发送完整JS

– Qwik:所有组件的JS都被懒加载到极致,用户点击按钮时才会下载handler

Qwik在首屏包体积上更激进,但它需要学习一套全新的框架($前缀、序列化、符号系统),生态远不如React成熟。如果你的团队已经熟悉React,Qwik的迁移成本很高。

RSC vs 传统SSR

很多React开发者已经在用SSR了,RSC比SSR多做了什么?

– SSR仍然需要把全套JS发给浏览器做水合

– RSC把非交互组件的JS完全剔除

– SSR的数据获取限制在 getServerSideProps 等固定API中,RSC可以在任意组件层级直接获取

developerway.com有一组实测数据:在产品页面这样的简单内容场景下,RSC让LCP从SSR的2.1s降到了1.1s。但在交互密集的仪表盘场景,RSC反而比CSR更慢——服务端渲染有时间开销。

选型参考

“`

你的应用交互密集吗?

├── 是 → RSC 需要搭配大量 Client Component

│      可以考虑:传统 CSR + 代码分割

└── 否 → 主要是内容展示?

    ├── 是 → 项目使用 React 吗?

    │   ├── 是 → RSC 是不错的选择

    │   └── 否 → 考虑 Astro

    └── 否 → 混合型

            RSC 适合,但需要做好边界规划

“`


总结

React Server Components是React自Hooks以来最大的一次架构革新。它不是「优化技巧」,而是一种新的思考方式——让服务端做服务端擅长的,让浏览器做浏览器擅长的。

在2026年,如果你在Next.js生态中开发内容型或有明确边界的应用,React Server Components值得认真考虑。但如果你需要在重度交互应用中追求零客户端JS,Astro或Qwik可能是更合适的起点。

关键不在于「它好不好」,而在于你的应用是什么、你的团队是谁。


📖 推荐阅读

看看这些跟react相关的文章,你可能会感兴趣:

用 Electron 构建桌面应用:React/Vue 前端框架集成实战指南

浅析:Next.js 15 为什么成为 Agentic AI 应用标准?

React Compiler 1.0 来了:以后useMemo 和 useCallback 可以删了?

React 19 与 Vue 3.6:两种不同的前端哲学

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注