docs(vercel-react-best-practices): 添加 Vercel React 最佳实践规则文档
- 添加 sections 定义文件,包含性能优化各领域分类 - 添加规则模板文件,规范文档结构和标签定义 - 添加异步操作优化规则,包括防止瀑布流、并行化、延迟等待等 - 添加包大小优化规则,包括避免桶式导入、动态导入、预加载等 - 添加服务端性能优化规则,包括 API 路
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: Avoid Shared Module State for Request Data
|
||||
impact: HIGH
|
||||
impactDescription: prevents concurrency bugs and request data leaks
|
||||
tags: server, rsc, ssr, concurrency, security, state
|
||||
---
|
||||
|
||||
## Avoid Shared Module State for Request Data
|
||||
|
||||
For React Server Components and client components rendered during SSR, avoid using mutable module-level variables to share request-scoped data. Server renders can run concurrently in the same process. If one render writes to shared module state and another render reads it, you can get race conditions, cross-request contamination, and security bugs where one user's data appears in another user's response.
|
||||
|
||||
Treat module scope on the server as process-wide shared memory, not request-local state.
|
||||
|
||||
**Incorrect (request data leaks across concurrent renders):**
|
||||
|
||||
```tsx
|
||||
let currentUser: User | null = null
|
||||
|
||||
export default async function Page() {
|
||||
currentUser = await auth()
|
||||
return <Dashboard />
|
||||
}
|
||||
|
||||
async function Dashboard() {
|
||||
return <div>{currentUser?.name}</div>
|
||||
}
|
||||
```
|
||||
|
||||
If two requests overlap, request A can set `currentUser`, then request B overwrites it before request A finishes rendering `Dashboard`.
|
||||
|
||||
**Correct (keep request data local to the render tree):**
|
||||
|
||||
```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>
|
||||
}
|
||||
```
|
||||
|
||||
Safe exceptions:
|
||||
|
||||
- Immutable static assets or config loaded once at module scope
|
||||
- Shared caches intentionally designed for cross-request reuse and keyed correctly
|
||||
- Process-wide singletons that do not store request- or user-specific mutable data
|
||||
|
||||
For static assets and config, see [Hoist Static I/O to Module Level](./server-hoist-static-io.md).
|
||||
Reference in New Issue
Block a user