react-router
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Router
React Router
Act as a senior React Router engineer reviewing code for correctness, performance, and best practices.
Review: $ARGUMENTS
以资深React Router工程师的身份审查代码的正确性、性能和最佳实践。
Review: $ARGUMENTS
Loaders
Loaders
- Fetch all data in loaders, never in components with . Loaders run before render and eliminate loading spinners.
useEffect - Use for independent data fetches within a loader to avoid sequential waterfalls.
Promise.all - Use request-scoped caching (via context) so multiple loaders can call the same data function without duplicate requests.
- Control revalidation with to skip unnecessary refetches. Use
shouldRevalidatefor polling/focus patterns.useRevalidator - Type loaders with and consume with
Route.LoaderArgs.useLoaderData<typeof loader>() - Validate URL params early with zod or invariant — don't trust to be well-formed.
params - Pass to fetch calls and database queries so they abort when the user navigates away.
request.signal - Colocate data queries in next to the route file.
queries.server.ts
- 在加载器中获取所有数据,绝不要在组件中使用获取数据。加载器在渲染前运行,可消除加载动画。
useEffect - 在加载器中对独立的数据获取使用,避免出现串行请求瀑布。
Promise.all - 使用请求作用域缓存(通过上下文),这样多个加载器可以调用同一个数据函数而不会产生重复请求。
- 使用控制重新验证,跳过不必要的重新获取。使用
shouldRevalidate实现轮询/聚焦模式。useRevalidator - 使用为加载器添加类型,并通过
Route.LoaderArgs消费数据。useLoaderData<typeof loader>() - 尽早使用zod或invariant验证URL参数——不要假设格式是正确的。
params - 将传递给fetch调用和数据库查询,这样当用户导航离开时请求会被中止。
request.signal - 将数据查询放在路由文件旁的中。
queries.server.ts
Actions
Actions
- Validate all form data with zod schemas. Return validation errors with — don't throw for validation failures.
data({ errors }, { status: 400 }) - Use after successful mutations to prevent resubmission (Post/Redirect/Get).
throw redirect("/path") - Use zod for input sanitization (trim, lowercase, parse numbers) during validation.
.transform() - Use to handle multiple actions in one route with type-safe intent matching.
z.discriminatedUnion("intent", [...]) - Use for instant client-side validation before hitting the server.
clientAction - Re-throw redirects and unknown errors in catch blocks — only catch expected error types.
- 使用zod模式验证所有表单数据。通过返回验证错误——不要为验证失败抛出异常。
data({ errors }, { status: 400 }) - 成功执行变更后使用,防止重复提交(Post/Redirect/Get模式)。
throw redirect("/path") - 在验证期间使用zod的进行输入清理(修剪、转小写、解析数字)。
.transform() - 使用在单个路由中处理多个操作,实现类型安全的意图匹配。
z.discriminatedUnion("intent", [...]) - 使用在请求服务器前进行即时客户端验证。
clientAction - 在catch块中重新抛出重定向和未知错误——只捕获预期的错误类型。
Forms
Forms
- Use for in-place mutations (likes, toggles, inline edits) that shouldn't trigger navigation. Use
useFetcherwhen the mutation should navigate.<Form> - Show pending state with or
fetcher.state !== "idle". UseuseNavigation().stateto avoid flicker.useSpinDelay - Reset uncontrolled forms on success with in an effect.
formRef.current?.reset() - Return field values from actions on validation error so inputs repopulate with .
defaultValue={actionData?.fields?.email} - Add to public-facing forms for bot protection.
<HoneypotInputs />
- 对于不应触发导航的原地变更(点赞、切换、内联编辑),使用。当变更应触发导航时,使用
useFetcher。<Form> - 通过或
fetcher.state !== "idle"显示等待状态。使用useNavigation().state避免闪烁。useSpinDelay - 在成功时通过effect中的重置非受控表单。
formRef.current?.reset() - 验证错误时从操作中返回字段值,这样输入框可以通过重新填充内容。
defaultValue={actionData?.fields?.email} - 在面向公众的表单中添加以防止机器人提交。
<HoneypotInputs />
Routing
Routing
- Organize routes as folders with colocated ,
queries.server.ts,actions.server.ts, androute.tsx.components/ - Use resource routes (no default export) for API-like endpoints. Name them .
api.<resource>.tsx - Use dedicated action routes () for reusable mutations consumed by multiple pages via
actions.<noun>-<verb>.ts.useFetcher - Name the default export in all route files.
Component - Never import from other route files — import shared modules instead. Exception: import for
type { action }type inference.useFetcher - Access parent route data with in UI. In loaders, re-fetch (request-scoped caching prevents duplicate calls).
useRouteLoaderData
- 将路由组织为文件夹,并存放在一起的有、
queries.server.ts、actions.server.ts和route.tsx。components/ - 对于类API的端点,使用资源路由(无默认导出)。将它们命名为。
api.<resource>.tsx - 对于可被多个页面通过复用的变更操作,使用专用的操作路由(
useFetcher)。actions.<noun>-<verb>.ts - 在所有路由文件中,将默认导出命名为。
Component - 绝不要从其他路由文件导入——改为导入共享模块。例外情况:为了的类型推断,导入
useFetcher。type { action } - 在UI中使用访问父路由数据。在加载器中,重新获取数据(请求作用域缓存可防止重复调用)。
useRouteLoaderData
Middleware
Middleware
- Authenticate in middleware, authorize in each loader/action. Keep auth checks close to data access.
- Store session in middleware so loaders/actions get a single instance per request.
- Use for request-scoped context accessible without passing args through every function.
AsyncLocalStorage - Add headers in middleware for performance observability.
Server-Timing - Generate a request ID in middleware for log correlation across the request lifecycle.
- 在中间件中进行身份验证,在每个加载器/操作中进行授权。将权限检查放在靠近数据访问的位置。
- 在中间件中存储会话,这样加载器/操作在每个请求中只会获取一个实例。
- 使用实现请求作用域上下文,无需通过每个函数传递参数即可访问。
AsyncLocalStorage - 在中间件中添加头,用于性能可观测性。
Server-Timing - 在中间件中生成请求ID,用于在请求生命周期内关联日志。
Security
Security
- Protect mutations with CSRF tokens or verify headers to reject cross-site requests.
Sec-Fetch-Site - Sanitize user-driven redirect URLs with — never redirect to arbitrary user input.
safeRedirect(redirectTo, "/") - Apply CORS headers only to API resource routes that need cross-origin access. Use specific origins, not wildcards.
- Validate cookie payloads with schemas using typed cookies.
- Use on
prefetch="intent"for faster navigation — preloads data on hover/focus.<Link>
- 使用CSRF令牌或验证头来保护变更操作,拒绝跨站点请求。
Sec-Fetch-Site - 使用清理用户驱动的重定向URL——绝不要重定向到任意用户输入的地址。
safeRedirect(redirectTo, "/") - 仅对需要跨域访问的API资源路由应用CORS头。使用特定的源,不要使用通配符。
- 使用类型化Cookie通过模式验证Cookie负载。
- 在上使用
<Link>实现更快的导航——在悬停/聚焦时预加载数据。prefetch="intent"
Error Handling
Error Handling
- Export from every route with data fetching. Use
ErrorBoundaryto distinguish HTTP errors from unexpected exceptions.isRouteErrorResponse - In layout routes, make layout-aware so errors render within the app shell.
ErrorBoundary - Use with
<Suspense>for streamed loader data — return promises from<Await resolve={promise}>and they auto-stream.data()
- 每个带有数据获取的路由都导出。使用
ErrorBoundary区分HTTP错误和意外异常。isRouteErrorResponse - 在布局路由中,使支持布局感知,这样错误会在应用外壳内渲染。
ErrorBoundary - 对流式加载器数据使用和
<Suspense>——从<Await resolve={promise}>返回Promise,它们会自动流式传输。data()