Next 和 Rsc
社区来稿 · Liu由用户发布,不代表 batype 本人观点
·712 字 · 约 2 分钟
React Server Components(RSC)和 Next.js
RSC(React Server Components)与 Next.js 常见问题整理#
1. RSC(React Server Components)是什么?#
- 只在服务端渲染的组件,不会被打包到客户端 JS。
- 可以直接访问数据库、API、文件等服务端资源。
- 目标:提升首屏性能、减小客户端 JS 体积、提升数据安全性。
2. RSC 的优缺点#
优点:
- 极致性能优化(减少客户端 JS 体积)
- 服务端可直接访问敏感资源
- 灵活组合 SSR/SPA/静态等渲染模式
- 数据获取逻辑可直接写在组件里
缺点/挑战:
- 生态尚未完全成熟
- 需要区分 Server/Client 组件,心智负担增加
- 调试和部署复杂度提升
- Server 组件不能用 useState/useEffect 等客户端 Hook
3. RSC 现在实际有应用吗?#
- Next.js 13/14 的 app router 已经原生支持 RSC,Vercel、Meta 等公司已在生产环境试点。
- 目前主流用法是 Next.js app 目录下的页面和组件。
4. 什么时候用 Server Component,什么时候用 Client Component?#
Server Component 适合:
- 只展示内容、无交互、无副作用的组件
- 需要服务端数据、SEO、数据库访问的组件
Client Component 适合:
- 需要响应用户交互(如点击、输入、动画等)
- 需要用 useState/useEffect/useRef/useReducer 等 Hook
- 需要访问浏览器 API 的组件
判断口诀:
- “能用 Server 就用 Server,需要交互再用 Client”
- “展示用 Server,交互用 Client”
5. Server Component 能用 useSWR/react-query 这类库吗?#
- 不能。Server Component 不能用 useSWR、react-query 等客户端数据请求库,也不能用 useEffect/useState。
- Server Component 推荐直接用 async/await、fetch、数据库查询等服务端数据获取方式。
- useSWR/react-query 只能在 Client Component 里用,适合需要前端动态请求、轮询、懒加载等场景。
6. Next.js 如何处理大量页面(如一千个文章详情)的渲染和打包?#
- Next.js 支持 SSG(静态生成)、SSR(服务端渲染)、ISR(增量静态生成)三种模式。
- 不会把所有页面都打包成静态资源,除非你在 generateStaticParams 里全部返回。
- 推荐用 ISR 或 SSR,按需生成和缓存页面,兼顾性能和实时性。
- app router 默认就是“智能按需渲染”,不会导致包体积暴涨。
7. 三种模式的代码实现(TypeScript 示例)#
SSG(静态生成)#
export async function generateStaticParams() {
const ids = await fetchAllPostIds();
return ids.map(id => ({ id }));
}
export default async function Page({ params }: { params: { id: string } }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await res.json();
return <div>{post.title}</div>;
}
SSR(服务端渲染)#
export default async function Page({ params }: { params: { id: string } }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`, {
cache: "no-store", // 强制 SSR
});
const post = await res.json();
return <div>{post.title}</div>;
}
ISR(增量静态生成)#
export async function generateStaticParams() {
const hotIds = await fetchHotPostIds();
return hotIds.map(id => ({ id }));
}
export default async function Page({ params }: { params: { id: string } }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`, {
next: { revalidate: 60 }, // 60秒自动后台更新
});
const post = await res.json();
return <div>{post.title}</div>;
}
8. revalidate: 60 的含义#
- 表示页面缓存 60 秒,后台自动更新一次。
- 不是每 60 秒主动刷新所有页面,而是“有访问才后台再生”。
- 绝大多数情况下,服务器压力远小于 SSR,且比纯 SSG 灵活。
- 可根据业务需求灵活调整 revalidate 的时间。
如需更详细的原理、代码或有其他问题,欢迎随时补充!