--- 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 } async function Dashboard() { return
{currentUser?.name}
} ``` 如果两个请求重叠,请求 A 可以设置 `currentUser`,然后请求 B 在请求 A 完成渲染 `Dashboard` 之前将其覆盖。 **正确做法(将请求数据保持在渲染树局部):** ```tsx export default async function Page() { const user = await auth() return } function Dashboard({ user }: { user: User | null }) { return
{user?.name}
} ``` 安全例外情况: - 在模块作用域一次性加载的不可变静态资源或配置 - 有意设计为跨请求复用且键值正确的共享缓存 - 不存储请求或用户特定可变数据的进程级单例 关于静态资源和配置,请参见 [Hoist Static I/O to Module Level](./server-hoist-static-io.md)。