1. 前言
在 Web 开发的江湖里,React 一直扮演着"前端大法师"的角色。
但是当用户们喊着:
"我的网页怎么还没加载出来!我要立刻马上看内容!"
React 有点尴尬了:
- 客户端渲染(CSR)?太慢了,用户要等 JS 下完再跑。
- 服务端渲染(SSR)?可以快,但每次都要重新跑逻辑。
于是,Next.js 披着 React 官方认证的斗篷,推出了一个新法宝:
✨ React Server Components(RSC) ------ 让你既能在服务端计算,又能在客户端交互,完美融合两界。
2. 什么是服务端组件(Server Components)?
先来一句文艺版解释:
服务端组件就像剧院的后台化妆师,观众永远见不到他在干啥,但最终效果直接呈现在舞台上。
再来一句计算机科学家版解释:
- 服务端组件在 Node.js 服务器环境 执行
- 可以访问 数据库 / 文件系统 / 后端 API
- 渲染结果是 纯 HTML,直接塞到浏览器里
- 不会打包进浏览器的 JS 代码里(减少 bundle 体积)
简单例子
javascript
// app/page.js (默认就是 Server Component)
export default function Page() {
const data = getDataFromDatabase(); // 这里可以直接查数据库
return <h1>Hello, {data.userName}</h1>;
}
👉 注意:这里不需要 "use client"
,它是纯服务端逻辑。
3. 什么是客户端组件("use client"
)?
既然有后台化妆师,就得有台前演员。观众要的是:
- 按钮点一下能弹窗
- 输入框打字要立刻更新
- 动画咻咻咻
这些交互逻辑必须跑在浏览器端。于是我们就需要 客户端组件。
如何定义客户端组件?
很简单:只要在文件开头加一句:
javascript
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
点击次数: {count}
</button>
);
}
👉 没有 "use client"
,useState
就会报错,因为服务端根本没有浏览器的事件系统。
4. 服务端组件 VS 客户端组件
来一张 ASCII 对比图:
diff
+----------------------+ +----------------------+
| Server Component | | Client Component |
+----------------------+ +----------------------+
| 运行在 Node.js 服务端 | | 运行在浏览器环境 |
| 可以直接访问数据库 | | 可以用 useState/useEffect|
| 不会打包进浏览器 | | 会被打包到 JS bundle |
| 初始渲染速度快 | | 提供交互体验 |
+----------------------+ +----------------------+
换个形象的比喻:
- 服务端组件:厨师在后厨炒好菜,直接端到你桌上。
- 客户端组件:你自己手里拿的刀叉、勺子、吸管,用来享受美食。
5. 混搭:服务端 + 客户端
Next.js 的强大之处就在于:
- 你可以在 服务端组件里引入客户端组件
- 但是 客户端组件不能引入服务端组件(因为浏览器没法跑服务端逻辑)
示例
javascript
// app/page.js (Server Component)
import Counter from "./Counter"; // 引入客户端组件
export default function Page() {
const user = { name: "Leon Gao" };
return (
<div>
<h1>欢迎,{user.name}</h1>
<Counter /> {/* 客户端交互 */}
</div>
);
}
👉 渲染过程:
-
服务端先生成 HTML:
less<div> <h1>欢迎,Leon Gao</h1> <button>点击次数: 0</button> </div>
-
浏览器再加载客户端 JS,把按钮变成"可点击的活组件"。
6. 底层原理小揭秘
React Server Components (RSC) 的黑魔法:
- 服务端组件渲染后,并不是直接吐 HTML,而是吐出一种 特殊的 JSON 协议(里面描述了组件树和 UI)。
- 浏览器端的 React 解析这个协议,把静态内容拼到页面上。
- 如果遇到
"use client"
的组件,就会打包对应的 JS,交给浏览器执行。
换句话说:
- 服务端组件负责"长相"
- 客户端组件负责"灵魂"
7. 什么时候用 Server?什么时候用 Client?
-
用 Server Component 的场景
- 页面数据来自数据库 / API
- 渲染大量静态内容(比如博客文章)
- 不需要交互
-
用 Client Component 的场景
- 有状态(useState, useEffect)
- 有交互(按钮点击、输入框、动画)
- 需要访问浏览器 API(如 localStorage)
👉 最佳实践:
能用服务端,就不要用客户端 。
因为每多一个客户端组件,bundle 就大一分,用户加载就慢一分。
8. 小结
- Server Components:轻、快、隐形的幕后英雄
- Client Components:活泼、互动、亲民的前台演员
- Next.js:导演,调度两者,完成一场完美的全栈大戏
所以,下次有人问你:
"Next.js 的 Server Component 和
use client
有啥区别?"
你就可以一脸轻松地回答:
"一个在后台炒菜,一个在前台上菜,你吃得香就是因为他们配合得好。"