React Production Engineering

一套完整的 React 生产级应用构建方法,涵盖架构、组件、状态管理与性能优化。

已扫描
适合谁
前端开发工程师、技术负责人或架构师
不适合谁
无 React 基础的新手开发者、仅需简单页面展示的非工程化项目
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @1kalin/afrexai-react-production

Skill 说明

命令、参数、文件名以原文为准

React 生产工程

构建生产级 React 应用的完整方法论。涵盖架构决策、组件设计、状态管理、性能优化、测试与部署 —— 不仅是 API 参考,更包含决策框架、模板和评分系统。

阶段 1:架构评估

快速健康检查(满分 16 分)

  • [ ] 组件树深度 < 6 层(+2 分)
  • [ ] 属性传递不超过 2 层(+2 分)
  • [ ] 打包体积 < 200KB(压缩后)(+2 分)
  • [ ] 4G 网络下 LCP < 2.5 秒(+2 分)
  • [ ] 业务逻辑测试覆盖率 > 70%(+2 分)
  • [ ] 生产代码中无 any 类型(+2 分)
  • [ ] 无直接 DOM 操作(+2 分)
  • [ ] 错误边界使用一致(+2 分)

架构简报

project:
  name: ""
  type: "" # spa | ssr | hybrid | static
  framework: "" # next | remix | vite-spa | astro
  scale: "" # small (<20 routes) | medium (20-100) | large (100+)
  team_size: "" # solo | small (2-5) | medium (6-15) | large (15+)
current_state:
  react_version: "" # 18 | 19
  typescript: true
  router: "" # react-router | next-app | tanstack-router
  state_management: "" # useState | zustand | jotai | redux | tanstack-query
  styling: "" # tailwind | css-modules | styled-components | vanilla-extract
  testing: "" # vitest | jest | playwright | cypress
  ci_cd: "" # github-actions | gitlab-ci | vercel
pain_points: []
goals: []

框架选择决策矩阵

因素Vite SPANext.jsRemixAstro
需要 SEO✅ 最佳✅ 良好✅ 最佳
仪表盘/应用类项目✅ 最佳✅ 良好✅ 良好
内容密集型✅ 良好✅ 良好✅ 最佳
团队熟悉度✅ 简单⚠️ 学习曲线⚠️ Web 标准⚠️ Islands
部署灵活性任意位置Vercel 最优任意位置任意位置
打包体积控制完全可控框架开销更小最小 JS

决策规则:

  1. 无需 SEO 的仪表盘或内部工具 → 使用 Vite SPA
  2. 营销页面与应用混合场景 → 使用 Next.js
  3. 以内容为主、带少量交互 → 使用 Astro
  4. 优先遵循 Web 标准、支持嵌套布局 → 使用 Remix
  5. 多数 SaaS 产品的默认选择 → 使用 Next.js

阶段 2:项目结构与规范

推荐的特征驱动结构

src/
├── app/                    # 路由/页面(框架相关)
├── features/               # 特征模块(核心模式)
│   ├── auth/
│   │   ├── components/     # 特征专属组件
│   │   ├── hooks/          # 特征专属自定义 Hook
│   │   ├── api/            # API 请求与类型定义
│   │   ├── utils/          # 特征专用工具函数
│   │   ├── types.ts        # 特征类型定义
│   │   └── index.ts        # 公共 API(导出聚合)
│   ├── dashboard/
│   └── settings/
├── shared/                 # 跨特征共享代码
│   ├── components/         # 通用 UI 组件
│   │   ├── ui/             # 原语组件(Button, Input, Card)
│   │   └── layout/         # 布局组件
│   ├── hooks/              # 通用自定义 Hook
│   ├── lib/                # 工具函数、常量
│   └── types/              # 全局类型定义
├── providers/              # Context 提供者
└── styles/                 # 全局样式

7 条结构规范

  1. 特征隔离features/ 目录之间禁止直接导入;应通过 shared/ 或事件通信
  2. 导出聚合 — 每个特征模块必须包含 index.ts 文件,定义其公共接口
  3. 就近存放 — 测试文件、故事文件和样式应与组件同级
  4. 最大文件大小 — 单个文件不超过 300 行;超出则需拆分
  5. 最大组件大小 — JSX 代码不超过 50 行;超出则需提取子组件
  6. 无循环依赖 — 使用 eslint-plugin-import 强制约束
  7. 类型就近存放 — 特征类型放在特征目录内,全局类型放在 shared/types

命名规范

组件:           PascalCase.tsx       (UserProfile.tsx)
自定义 Hook:    useCamelCase.ts      (useAuth.ts)
工具函数:        camelCase.ts         (formatCurrency.ts)
类型定义:        PascalCase.ts        (User.ts)或 types.ts
常量:           SCREAMING_SNAKE.ts   (API_ENDPOINTS.ts)
测试文件:        *.test.tsx           (UserProfile.test.tsx)
故事文件:        *.stories.tsx        (Button.stories.tsx)

阶段 3:组件设计模式

组件结构模板

// 1. 导入(分组:react → 第三方库 → 内部模块 → 类型 → 样式)
import { useState, useCallback, memo } from 'react'
import { clsx } from 'clsx'
import { Button } from '@/shared/components/ui'
import type { User } from '../types'

// 2. 类型定义(对外暴露,供复用)
export interface UserCardProps {
  user: User
  onEdit?: (id: string) => void
  variant?: 'compact' | 'full'
  className?: string
}

// 3. 组件(命名导出,非默认导出)
export const UserCard = memo(function UserCard({
  user,
  onEdit,
  variant = 'full',
  className,
}: UserCardProps) {
  // 4. 自定义 Hook 优先
  const [isExpanded, setIsExpanded] = useState(false)

  // 5. 派生状态(不使用 useEffect 计算派生值!)
  const displayName = `${user.firstName} ${user.lastName}`

  // 6. 事件处理器(使用 useCallback 以避免不必要的重新创建)
  const handleEdit = useCallback(() => {
    onEdit?.(user.id)
  }, [onEdit, user.id])

  // 7. 边界情况提前返回
  if (!user) return null

  // 8. JSX(最多 50 行)
  return (
    <div className={clsx('rounded-lg border p-4', className)}>
      <h3>{displayName}</h3>
      {variant === 'full' && <p>{user.bio}</p>}
      {onEdit && <Button onClick={handleEdit}>编辑</Button>}
    </div>
  )
})

组件组合模式

1. 复合组件(用于相关 UI 组)

// 使用方式: <Tabs><Tabs.List><Tabs.Tab>A</Tabs.Tab></Tabs.List><Tabs.Panel>...</Tabs.Panel></Tabs>
const TabsContext = createContext<TabsContextType | null>(null)

export function Tabs({ children, defaultValue }: TabsProps) {
  const [activeTab, setActiveTab] = useState(defaultValue)
  return (
    <TabsContext.Provider value={{ activeTab, setActiveTab }}>
      {children}
    </TabsContext.Provider>
  )
}
Tabs.List = TabsList
Tabs.Tab = TabsTab
Tabs.Panel = TabsPanel

2. 渲染属性(用于灵活的渲染逻辑)

export function DataList<T>({ items, renderItem, renderEmpty }: DataListProps<T>) {
  if (items.length === 0) return renderEmpty?.() ?? <EmptyState />
  return <ul>{items.map((item, i) => <li key={i}>{renderItem(item)}</li>)}</ul>
}

3. 高阶组件(用于跨切面关注点 — 建议谨慎使用)

export function withAuth<P>(Component: ComponentType<P>) {
  return function AuthenticatedComponent(props: P) {
    const { user, isLoading } = useAuth()
    if (isLoading) return <Spinner />
    if (!user) return <Navigate to="/login" />
    return <Component {...props} />
  }
}

10 个组件设计规范

  1. 一个文件一个组件 — 始终遵循
  2. 使用命名导出 — 永远不要使用默认导出(提升重构安全性)
  3. 显式定义 Props 接口 — 必须明确,且必须导出
  4. 组件中不包含业务逻辑 — 应提取至自定义 Hook
  5. 禁止内联样式 — 使用 Tailwind 类名或 CSS Modules
  6. 禁止字符串 ref — 仅使用 useRef
  7. 禁止使用索引作为 key — 使用稳定标识符
  8. 按需使用 memo — 不是所有地方都用,仅用于昂贵的渲染场景
  9. 优先使用 children 而非 props — 更推荐组合而非配置
  10. 默认具备可访问性 — 使用语义化 HTML,必要时添加 ARIA 属性

阶段 4:状态管理决策框架

状态类型决策树

是否为服务器数据(来自 API)?
├─ 是 → 使用 TanStack Query(或 SWR)—— 服务器状态绝不使用 Redux/Zustand
│
└─ 否 → 是否在多个功能间共享?
    ├─ 是 → 是否复杂且涉及多种操作?
    │   ├─ 是 → 使用 Zustand(或团队熟悉 Redux Toolkit)
    │   └─ 否 → 使用 Jotai(原子化状态)或 Zustand(简单状态存储)
    │
    └─ 否 → 是否在单个功能内共享?
        ├─ 是 → 使用 Context + useReducer(或 Zustand 功能模块)
        └─ 否 → 使用 useState / useReducer(组件本地状态)

状态管理工具对比

工具适用场景包大小学习难度团队规模
useState组件本地状态0 KB任意
useReducer复杂本地状态0 KB任意
Context功能范围内的状态,更新频率低0 KB任意
Zustand全局客户端状态1.1 KB任意
Jotai原子化派生状态3.4 KB中等小型至中型
TanStack Query服务器状态12 KB中等任意
Redux Toolkit复杂全局状态 + 中间件11 KB大型

使用 TanStack Query 管理服务器状态

// api/users.ts — 查询键工厂模式
export const userKeys = {
  all: ['users'] as const,
  lists: () => [...userKeys.all, 'list'] as const,
  list: (filters: Filters) => [...userKeys.lists(), filters] as const,
  details: () => [...userKeys.all, 'detail'] as const,
  detail: (id: string) => [...userKeys.details(), id] as const,
}

// hooks/useUsers.ts
export function useUsers(filters: Filters) {
  return useQuery({
    queryKey: userKeys.list(filters),
    queryFn: () => fetchUsers(filters),
    staleTime: 5 * 60 * 1000, // 5 分钟
    placeholderData: keepPreviousData,
  })
}

export function useUpdateUser() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: updateUser,
    onMutate: async (newUser) => {
      // 乐观更新
      await queryClient.cancelQueries({ queryKey: userKeys.detail(newUser.id) })
      const previous = queryClient.getQueryData(userKeys.detail(newUser.id))
      queryClient.setQueryData(userKeys.detail(newUser.id), newUser)
      return { previous }
    },
    onError: (err, newUser, context) => {
      queryClient.setQueryData(userKeys.detail(newUser.id), context?.previous)
    },
    onSettled: (data, err, variables) => {
      queryClient.invalidateQueries({ queryKey: userKeys.detail(variables.id) })
      queryClient.invalidateQueries({ queryKey: userKeys.lists() })
    },
  })
}

使用 Zustand 管理客户端状态

// stores/useUIStore.ts — 聚焦、轻量的状态存储
interface UIStore {
  sidebarOpen: boolean
  theme: 'light' | 'dark' | 'system'
  toggleSidebar: () => void
  setTheme: (theme: UIStore['theme']) => void
}

export const useUIStore = create<UIStore>()(
  persist(
    (set) => ({
      sidebarOpen: true,
      theme: 'system',
      toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
      setTheme: (theme) => set({ theme }),
    }),
    { name: 'ui-preferences' }
  )
)

// 使用方式:const theme = useUIStore((s) => s.theme) — 始终使用选择器!

5 条状态管理规则

  1. 服务器状态 ≠ 客户端状态 — 永远不要将两者混在同一状态存储中
  2. 作用域最小化 — 优先级:useState > Context > Zustand > Redux
  3. 禁止使用 useEffect 管理派生状态 — 使用 useMemo 或直接计算
  4. 始终使用选择器useStore(s => s.field) 而非 useStore()
  5. URL 即状态 — 搜索参数、筛选条件、分页信息 → 应通过 URL 传递,而非 React 状态

阶段 5:自定义 Hook 工程实践

自定义 Hook 模板

// hooks/useDebounce.ts
export function useDebounce<T>(value: T, delayMs: number = 300): T {
  const [debouncedValue, setDebouncedValue] = useState(value)

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delayMs)
    return () => clearTimeout(timer)
  }, [value, delayMs])

  return debouncedValue
}

核心自定义 Hook 库

Phase 5: Custom Hooks Design

常用自定义 Hook 列表

Hook用途使用场景
useDebounce防抖值变化搜索输入框、窗口大小调整
useMediaQuery响应式断点检测条件渲染
useLocalStorage本地持久化状态用户偏好设置、草稿保存
useIntersection可见性检测懒加载、无限滚动
usePrevious记录上一次值动画效果、值对比
useClickOutside检测外部点击下拉菜单、模态框
useEventListener安全绑定事件键盘、滚动、窗口大小变化
useToggle布尔状态切换模态框、折叠面板

自定义 Hook 设计规范(超越 React 基础规则)

  1. 单一职责原则 — 每个 Hook 只负责一个功能,例如使用 useUserSearch 而非 useEverything
  2. 返回值格式统一 — 返回元组适用于 1-2 个值,返回对象适用于 3 个及以上值
  3. 接受配置对象参数 — 如 useDebounce(value, { delay: 300 }) 更易扩展和维护
  4. 妥善处理清理逻辑 — 所有订阅或定时器必须在 useEffect 的返回函数中进行清理
  5. 禁止在条件中使用 Hook — 条件逻辑应在 Hook 内部处理,避免在 ifswitch 中调用
  6. 独立测试 Hook — 使用 testing-library 提供的 renderHook 进行单元测试

Phase 6: TypeScript 集成

严格类型配置

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

核心类型模式

// 1. 区分式联合类型(用于状态机)
type AsyncState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error }

// 2. 多态组件(支持自定义标签)
type ButtonProps<C extends ElementType = 'button'> = {
  as?: C
  variant?: 'primary' | 'secondary'
} & ComponentPropsWithoutRef<C>

export function Button<C extends ElementType = 'button'>({
  as,
  variant = 'primary',
  ...props
}: ButtonProps<C>) {
  const Component = as || 'button'
  return <Component {...props} />
}

// 3. 品牌类型(用于区分 ID 类型)
type UserId = string & { __brand: 'UserId' }
type PostId = string & { __brand: 'PostId' }

// 4. 使用 Zod 进行运行时验证
const userSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  role: z.enum(['admin', 'user', 'viewer']),
})
type User = z.infer<typeof userSchema>

TypeScript 五大核心规则

  1. **禁止使用 any** — 改用 unknown 并逐步缩小范围,或使用泛型
  2. 在边界处使用 Zod — 所有外部数据(API 响应、表单、URL 参数)必须进行验证
  3. 优先使用区分式联合类型 — 推荐 { status: 'success'; data: T } 而非 { data?: T; error?: Error }
  4. 为 ID 使用品牌类型 — 防止将 userId 错误传入需要 postId 的位置
  5. **使用 satisfies 而非 as** — config satisfies Config 保留类型推断;as Config 会误导类型系统

Phase 7: 性能优化

性能预算指标

指标目标值测量方式
首次内容绘制(FCP)< 1.8 秒Lighthouse
最大内容绘制(LCP)< 2.5 秒Lighthouse
交互至下一帧(INP)< 200 毫秒Lighthouse
累积布局偏移(CLS)< 0.1Lighthouse
打包体积(压缩后)< 200 KBwebpack-bundle-analyzer
主线程 JavaScript 执行时间< 3 秒Chrome DevTools

优化优先级排序

优先级优化手段影响力工作量
P0路由级代码分割🔴 高
P0图片优化(next/image、srcset)🔴 高
P1树摇(Tree Shaking,使用命名导入)🟡 中等
P1长列表虚拟化🟡 中等中等
P1对耗时操作进行防抖🟡 中等
P2对昂贵组件使用 React.memo🟢 低至中等
P2对复杂计算使用 useMemo/useCallback🟢 低至中等
P3将重计算任务移至 Web Workers🟢 低

代码分割模式

// 1. 路由级分割(Next.js 自动支持,React Router 需手动配置)
const Dashboard = lazy(() => import('./features/dashboard'))
const Settings = lazy(() => import('./features/settings'))

// 2. 组件级分割(大型组件)
const Chart = lazy(() => import('./components/Chart'))
const MarkdownEditor = lazy(() =>
  import('./components/MarkdownEditor').then(m => ({ default: m.MarkdownEditor }))
)

// 3. 第三方库级分割(重型依赖)
const { PDFViewer } = await import('@react-pdf/renderer')

React Compiler(React 19+)

// 启用 React Compiler 后,无需手动使用 useMemo/useCallback/useMemo
// 编译器自动进行记忆化处理:
// ❌ const memoized = useMemo(() => expensiveCalc(data), [data])
// ✅ const memoized = expensiveCalc(data)  // 编译器自动处理

// 在 babel.config.js 中启用:
// plugins: [['babel-plugin-react-compiler', {}]]

渲染性能最佳实践

  1. 禁止在组件内部创建组件 — 组件应在模块顶层定义
  2. 禁止在 JSX 中创建对象或数组 — 如 style={{ color: 'red' }} 会导致每次重新渲染
  3. 使用子组件作为 props 避免不必要的重渲染<Layout><ExpensiveChild /></Layout>
  4. key 必须稳定且唯一 — 不要使用索引,也不要使用 Math.random()
  5. 避免上下文值频繁变更 — 可通过 memoize 提供值,或拆分多个上下文
  6. 优化前先进行性能分析 — 使用 React DevTools Profiler,而非凭直觉猜测

Phase 8: 错误处理与系统韧性

// 三级错误边界:
// 1. 应用级(捕获所有错误,显示完整页面错误)
// 2. 功能级(隔离功能失败)
// 3. 组件级(用于高风险组件——图表、第三方)

// 使用现代错误边界库 react-error-boundary
import { ErrorBoundary, FallbackProps } from 'react-error-boundary'

function FeatureErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
  return (
    <div role="alert" className="rounded-lg border-red-200 bg-red-50 p-4">
      <h3>发生错误</h3>
      <pre className="text-sm text-red-600">{error.message}</pre>
      <button onClick={resetErrorBoundary}>重试</button>
    </div>
  )
}

// 使用方式:
<ErrorBoundary FallbackComponent={FeatureErrorFallback} onReset={() => queryClient.clear()}>
  <DashboardFeature />
</ErrorBoundary>

错误处理检查清单

  • [ ] 应用级错误边界包裹整个应用
  • [ ] 每个主要功能都配置功能级错误边界
  • [ ] API 错误通过 TanStack Query 的 onError 或错误状态处理
  • [ ] 表单验证错误以内联方式显示(不使用弹窗提示)
  • [ ] 未知路由返回 404 页面
  • [ ] 离线状态检测与优雅降级
  • [ ] 错误上报至监控系统(如 Sentry 等)
  • [ ] 用户友好的错误提示(生产环境不显示堆栈信息)

阶段 9:表单与验证

表单库选型

适用场景包大小渲染方式
React Hook Form多数表单9 KB最小化(非受控)
Formik简单表单13 KB每次输入都渲染
TanStack Form类型安全的复杂表单5 KB受控
原生 HTML1-2 字段的小表单0 KB完全由你控制

默认推荐:React Hook Form + Zod

表单模式

const schema = z.object({
  email: z.string().email('无效的邮箱'),
  password: z.string().min(8, '至少 8 个字符'),
  role: z.enum(['admin', 'user']),
})
type FormData = z.infer<typeof schema>

export function LoginForm({ onSubmit }: { onSubmit: (data: FormData) => void }) {
  const form = useForm<FormData>({
    resolver: zodResolver(schema),
    defaultValues: { email: '', password: '', role: 'user' },
  })

  return (
    <form onSubmit={form.handleSubmit(onSubmit)} noValidate>
      <label htmlFor="email">邮箱</label>
      <input id="email" type="email" {...form.register('email')} aria-invalid={!!form.formState.errors.email} />
      {form.formState.errors.email && (
        <p role="alert">{form.formState.errors.email.message}</p>
      )}
      {/* ... 更多字段 */}
      <button type="submit" disabled={form.formState.isSubmitting}>
        {form.formState.isSubmitting ? '登录中...' : '登录'}
      </button>
    </form>
  )
}

阶段 10:测试策略

React 测试金字塔

层级工具覆盖率目标测试内容
单元测试Vitest80% 业务逻辑Hooks、工具函数、reducers
组件测试Testing Library关键用户流程渲染、交互、可访问性
集成测试Testing Library功能流程多组件协作流程
端到端测试Playwright核心路径登录、结账、核心流程
视觉测试Chromatic/PercyUI 组件回归检测

测试模式

// 组件测试(Testing Library 原则:测试行为,而非实现)
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

describe('UserCard', () => {
  it('点击编辑按钮时调用 onEdit 回调', async () => {
    const user = userEvent.setup()
    const onEdit = vi.fn()
    render(<UserCard user={mockUser} onEdit={onEdit} />)

    await user.click(screen.getByRole('button', { name: /编辑/i }))
    expect(onEdit).toHaveBeenCalledWith(mockUser.id)
  })

  it('当未提供 onEdit 时不渲染编辑按钮', () => {
    render(<UserCard user={mockUser} />)
    expect(screen.queryByRole('button', { name: /编辑/i })).not.toBeInTheDocument()
  })
})

7 条测试规则

  1. 测试行为,而非实现 — 不直接测试状态或 useEffect
  2. 使用可访问性查询getByRole > getByTestId > getByText
  3. 使用用户事件而非 fireEventuserEvent.click 模拟真实交互
  4. 每个概念一个断言 — 不是每测试一个断言,而是聚焦于单一概念
  5. 在边界处模拟 — 模拟 API 调用,而非内部函数
  6. 不使用快照测试 — 快照会因每次改动而失效,且无实际意义
  7. 采用 Arrange-Act-Assert 结构 — 每个测试保持清晰结构

阶段 11:无障碍访问(a11y)

10 项无障碍检查清单

  1. 语义化 HTML — 使用 <button> 而非 <div onClick>,使用 <nav> 而非 <div class="nav">
  2. 键盘导航 — 所有交互元素可通过 Tab 键访问,支持 Enter/Space 键操作
  3. 焦点管理 — 显示焦点指示器,Tab 顺序合理,模态框内使用焦点陷阱
  4. 替代文本 — 所有 <img> 都有描述性 alt 属性(或 alt="" 表示装饰性图片)
  5. 颜色对比度 — 正常文字至少 4.5:1,大文字至少 3:1(符合 WCAG AA)
  6. ARIA 标签 — 图标按钮使用 aria-label,提示信息使用 aria-describedby
  7. 实时区域 — 动态内容(如通知、表单错误)使用 aria-live="polite"
  8. 减少动画 — 尊重 prefers-reduced-motion 设置,避免不必要的动画
  9. 屏幕阅读器测试 — 使用 VoiceOver(Mac)或 NVDA(Windows)进行测试
  10. 自动化扫描 — 在 CI 中集成 axe-core(使用 vitest-axe@axe-core/playwright

阶段 12:生产部署检查清单

必须项(P0)

  • [ ] 启用 TypeScript 严格模式,构建无错误
  • [ ] 所有测试通过
  • [ ] 打包分析完成,无意外的大依赖
  • [ ] 应用级和功能级错误边界已配置
  • [ ] 环境变量在构建时已验证
  • [ ] 安全头已配置(CSP、HSTS、X-Frame-Options)
  • [ ] SEO 元标签已添加(title、description、OG 标签)
  • [ ] 分析与错误监控已集成
  • [ ] 性能预算达标(LCP < 2.5s)

推荐项(P1)

  • [ ] 使用 Storybook 构建组件库
  • [ ] 添加视觉回归测试
  • [ ] 在 CI 中集成自动化无障碍检查(a11y)
  • [ ] 为高风险功能启用特性开关(Feature Flags)
  • [ ] 为 PR 提供预览部署环境
  • [ ] 包体积 CI 检查(体积增加超过 10% 则失败)

推荐技术栈(2025+)

层级推荐方案备选方案
框架Next.js 15Remix、Vite SPA
语言TypeScript(严格模式)
样式Tailwind CSS v4CSS Modules
组件库shadcn/uiRadix、Headless UI
状态管理(服务端)TanStack Query v5SWR
状态管理(客户端)ZustandJotai
表单处理React Hook Form + ZodTanStack Form
测试框架Vitest + Testing LibraryJest
端到端测试PlaywrightCypress
代码规范BiomeESLint + Prettier
认证系统Auth.js(NextAuth)Clerk、Lucia
数据库Drizzle ORMPrisma
部署平台VercelCloudflare、Fly.io
监控工具SentryDatadog

质量评分标准(0-100)

维度权重评分内容
架构设计20%结构合理性、分层清晰度、设计模式应用
类型安全15%严格 TypeScript,禁止使用 any,Zod 边界校验
性能表现15%核心网页指标(Core Web Vitals)、包体积控制
测试质量15%测试覆盖率、测试质量、测试金字塔结构
无障碍访问10%符合 WCAG AA 标准,支持键盘操作与屏幕阅读器
状态管理10%工具选择合理,避免深层属性传递(prop drilling)
错误处理10%设置错误边界,用户友好提示,集成监控
开发者体验5%代码格式化、静态检查、CI 执行速度

评分等级:

90+:世界级水平|75-89:生产就绪|60-74:需改进|<60:技术债危机


10 个常见错误

#错误点修复建议
1useEffect 中计算派生状态改用内联计算或 useMemo
2属性传递深度超过 5 层使用 Context、Zustand 或组合模式
3useEffect 中发起数据请求使用 TanStack Query 或框架数据加载机制
4大量使用默认导出优先使用命名导出以提升重构安全性
5测试实现细节而非行为使用 Testing Library 测试用户行为
6单个组件代码超过 500 行拆分为独立的 hooks 和子组件
7缺少错误边界在应用层、功能层和组件层添加错误边界
8用 Redux 管理服务端状态使用 TanStack Query 管理 API 数据
9将无障碍访问留到最后才处理从第一天起就构建可访问性
10未开启 TypeScript 严格模式启用 strict 模式并解决所有错误

自然语言指令

  • “设置一个新 React 项目” → 执行第 1-2 阶段架构与结构搭建
  • “评审我的组件” → 应用第 3 阶段规则与质量评分
  • “帮我选择状态管理方案” → 启动第 4 阶段决策树
  • “优化性能” → 参考第 7 阶段优先级清单与性能分析
  • “添加错误处理” → 遵循第 8 阶段错误边界架构
  • “构建一个表单” → 采用第 9 阶段 React Hook Form + Zod 模式
  • “为这个组件编写测试” → 应用第 10 阶段测试模式
  • “检查无障碍访问” → 执行第 11 阶段检查清单
  • “准备上线发布” → 完成第 12 阶段部署检查清单
  • “审计我的 React 项目” → 全面评估各阶段质量得分
  • “从类组件迁移” → 采用现代模式与 Hooks 重构
  • “升级到 React 19” → 使用 Compiler、Server Components 与 Actions

⚡ 提升你的 React 开发能力

本技能提供系统化方法论。如需行业特定实现模式,可获取 AfrexAI 上下文包($47):

  • SaaS 上下文包 — SaaS 场景下的 React 模式、计费界面、仪表盘架构
  • 金融科技上下文包 — 金融类 UI 模式、实时数据处理、合规要求
  • 医疗健康上下文包 — HIPAA 合规 UI、患者数据处理规范

👉 浏览全部 10 个上下文包: https://afrexai-cto.github.io/context-packs/

🔗 AfrexAI 免费技能推荐

  • afrexai-nextjs-production — Next.js 生产工程实践
  • afrexai-vibe-coding — AI 辅助开发方法论
  • afrexai-technical-seo — React SPA 与 SSR 的技术 SEO
  • afrexai-test-automation-engineering — 完整的测试策略
  • afrexai-ui-design-system — 设计系统架构
1
@1kalin

已收录 10 个 Skill

相关推荐