Files
skillhub-088-vercel-react-b…/rules/server-no-shared-module-state.md
2026-07-13 21:36:17 +08:00

51 lines
1.7 KiB
Markdown

---
title: Avoid Shared Module State for Request Data
impact: HIGH
impactDescription: 防止并发 bug 和请求数据泄漏
tags: server, rsc, ssr, concurrency, security, state
---
## 避免为请求数据使用共享模块状态
对于 React Server Components 以及在 SSR 期间渲染的客户端组件,应避免使用可变的模块级变量来共享请求范围内的数据。服务端渲染可以在同一进程中并发执行。如果一个渲染向共享模块状态写入数据,而另一个渲染读取该状态,就可能出现竞态条件、跨请求污染以及安全漏洞,导致一个用户的数据出现在另一个用户的响应中。
请将服务端的模块作用域视为进程级的共享内存,而非请求局部状态。
**错误做法(请求数据在并发渲染间泄漏):**
```tsx
let currentUser: User | null = null
export default async function Page() {
currentUser = await auth()
return <Dashboard />
}
async function Dashboard() {
return <div>{currentUser?.name}</div>
}
```
如果两个请求重叠,请求 A 可以设置 `currentUser`,然后请求 B 在请求 A 完成渲染 `Dashboard` 之前将其覆盖。
**正确做法(将请求数据保持在渲染树局部):**
```tsx
export default async function Page() {
const user = await auth()
return <Dashboard user={user} />
}
function Dashboard({ user }: { user: User | null }) {
return <div>{user?.name}</div>
}
```
安全例外情况:
- 在模块作用域一次性加载的不可变静态资源或配置
- 有意设计为跨请求复用且键值正确的共享缓存
- 不存储请求或用户特定可变数据的进程级单例
关于静态资源和配置,请参见 [Hoist Static I/O to Module Level](./server-hoist-static-io.md)。