服务端阅读 06月2日 23:11
React Server Components 是什么?和 Client Components 怎么配合?
React Server Components(RSC)是只在服务端渲染的组件——它们的代码不会发送到浏览器。这是 React 架构的根本变化:组件不再默认跑在客户端,而是默认跑在服务端。RSC 解决什么问题传统 React 应用把所有组件代码打包成 JS 发给浏览器。一个列表页可能有 200KB 的 JS,但大部分是数据获取和渲染逻辑,用户交互只占一小部分。用户要等 JS 下载、解析、执行完才能看到页面。RSC 的解决方案:数据获取和渲染在服务端完成,只把 HTML 和少量交互代码发给浏览器。结果:更快的首屏、更小的 JS 包、更简单的数据获取。Server Component vs Client Component// Server Component(默认)— 不发 JS 给浏览器async function ArticleList() { const articles = await db.article.findMany(); // 直接查数据库 return ( <ul> {articles.map(a => <li key={a.id}>{a.title}</li>)} </ul> );}// Client Component — JS 会发给浏览器'use client'import { useState } from 'react';function SearchBox() { const [query, setQuery] = useState(''); // 需要状态 return <input value={query} onChange={e => setQuery(e.target.value)} />;}判断标准很简单:需要 useState、useEffect、onClick 等 React hooks/事件的就是 Client Component,否则就是 Server Component。数据获取方式的变化Pages Router 时代,客户端获取数据:// Pages Router — 客户端获取useEffect(() => { fetch('/api/articles').then(r => r.json()).then(setArticles);}, []);App Router + RSC,服务端直接获取:// App Router — 服务端获取async function Page() { const articles = await db.article.findMany(); return <ArticleList articles={articles} />;}不需要 API 路由,不需要 loading 状态管理,不需要客户端缓存。服务端拿到数据直接渲染成 HTML。组合模式Server Component 可以渲染 Client Component,但反过来不行:// Server Componentimport SearchBox from './SearchBox'; // Client Componentasync function Page() { const data = await fetchData(); return ( <div> <SearchBox /> {/* Client Component:交互 */} <ArticleList data={data} /> {/* Server Component:展示 */} </div> );}关键规则:Server Component 可以 import 和渲染 Client ComponentClient Component 不能 import Server ComponentServer Component 可以通过 props 把数据传给 Client Component(必须是可序列化的数据)什么时候用 Client Component只有这四种情况需要 'use client':需要交互(onClick、onChange)需要状态(useState、useReducer)需要生命周期(useEffect)需要浏览器 API(window、localStorage)其他都用 Server Component。一个常见错误:因为不熟悉 RSC 而给所有组件加 'use client'——这样 App Router 就退化成了 Pages Router,失去了 RSC 的性能优势。RSC 的局限Server Component 不能用 hooks(useState、useEffect)Server Component 不能用浏览器 API(window、document)Server Component 传给 Client Component 的 props 必须可序列化(不能传函数、类实例)调试更难——错误堆栈跨服务端和客户端RSC 仍然在快速演进,API 可能在未来版本变化。但方向是明确的:服务端渲染更多,客户端 JS 更少。