react-规范.mdc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. ---
  2. description: LabelStudio 客户端应用的 React 编码标准和最佳实践
  3. globs: **/*.jsx,**/*.tsx
  4. ---
  5. # React 最佳实践
  6. ## 项目结构
  7. - 所有前端代码位于 `web` 目录
  8. - 主应用代码位于 `web/apps/labelstudio`
  9. - 共享库位于 `web/libs`
  10. - 遵循既定的目录结构:
  11. - `components/`: 可复用的 UI 组件
  12. - `pages/`: 顶层页面组件
  13. - `utils/`: 工具函数
  14. - `hooks/`: 自定义 React Hooks
  15. - `atoms/`: Jotai 原子状态定义
  16. - `providers/`: Context 提供者
  17. - `services/`: API 和其他服务
  18. - `types/`: TypeScript 类型定义
  19. - `assets/`: 静态资源
  20. ## 组件结构
  21. - 使用函数组件而非类组件
  22. - 保持组件小而专注
  23. - 将可复用逻辑提取到自定义 Hooks
  24. - 使用组合而非继承
  25. - 使用 TypeScript 实现适当的 prop 类型
  26. - 将大组件拆分为更小、更专注的组件
  27. - 遵循一致的文件组织模式:
  28. ```
  29. component-name/
  30. component-name.tsx
  31. component-name.module.scss
  32. component-name.test.tsx
  33. index.ts
  34. ```
  35. ## Hooks
  36. - 遵循 Hooks 规则
  37. - 使用自定义 Hooks 实现可复用逻辑
  38. - 保持 Hooks 专注和简单
  39. - 除非绝对必要,否则避免使用 useEffect
  40. - 在 useEffect 中使用适当的依赖数组
  41. - 在 useEffect 中实现清理逻辑
  42. - 避免嵌套 Hooks
  43. ## 状态管理
  44. - 使用 useState 管理本地组件状态
  45. - 使用 Jotai 原子而非 Context API 管理共享状态
  46. - 使用 atomWithReducer 处理复杂状态逻辑
  47. - 使用 atomWithQuery 处理任何 API 数据请求
  48. - 将状态保持在尽可能接近使用位置的地方
  49. - 通过适当的状态管理避免 prop drilling
  50. - 仅使用 Jotai 作为全局状态管理的单一数据源
  51. ## 性能
  52. - 实现适当的记忆化(useMemo, useCallback)
  53. - 对昂贵的组件使用 React.memo
  54. - 避免不必要的重渲染
  55. - 实现适当的懒加载
  56. - 在列表中使用适当的 key props
  57. - 分析和优化渲染性能
  58. ## 工具
  59. - 使用 Biome 进行代码检查和格式化
  60. - 遵循 .stylelintrc.json 中定义的 CSS/SCSS 检查规则
  61. - 使用 TypeScript 确保类型安全
  62. - 通过监控导入来控制打包大小
  63. ## 表单
  64. - 对表单输入使用受控组件
  65. - 实现适当的表单验证
  66. - 正确处理表单提交状态
  67. - 显示适当的加载和错误状态
  68. - 对复杂表单使用表单库
  69. - 为表单实现适当的无障碍功能
  70. ## 错误处理
  71. - 实现错误边界
  72. - 正确处理异步错误
  73. - 显示用户友好的错误消息
  74. - 实现适当的后备 UI
  75. - 适当记录错误
  76. - 优雅处理边缘情况
  77. ## 测试
  78. - 为组件编写单元测试
  79. - 为复杂流程实现集成测试
  80. - 使用 React Testing Library
  81. - 测试用户交互
  82. - 测试错误场景
  83. - 实现适当的模拟数据
  84. ## 无障碍性
  85. - 确保组件符合 WCAG 2.1 AA 标准
  86. - 使用语义化 HTML 元素
  87. - 实现适当的 ARIA 属性
  88. - 确保键盘导航
  89. - 使用屏幕阅读器测试
  90. - 处理焦点管理
  91. - 为图片提供适当的 alt 文本
  92. ## 代码组织
  93. - 使用适当的文件命名约定,采用 kebab-case,例如 ListItem -> `list-item.tsx`
  94. - 优先每个文件夹一个组件,但必要时将相关组件分组在一起,确保每个文件只有一个组件
  95. - 组件文件夹应包含一个 SCSS `.module.scss` 文件,文件名为组件的 kebab-case 形式,例如 ListItem -> `list-item.module.scss`
  96. - 实现适当的目录结构
  97. - UI 组件位于 `web/libs/ui`
  98. - 跨应用共享的应用组件(如某些页面级块)位于 `web/libs/app-common`
  99. - `web/apps` 中的代码只能从 `web/libs` 导入,`web/libs` 不能从 `web/apps` 导入
  100. - `web/libs/app-common` 中的代码只能从其他 `web/libs` 或 `web/apps` 导入。其他 `web/libs` 不能从 `web/libs/app-common` 导入
  101. - 将原子保存在全局 atoms 文件夹中,文件名与实体或状态意图匹配
  102. - 通过将 story 文件与组件文件放在一起,将所有组件及其状态添加到 Storybook,例如 `list-item.stories.tsx`
  103. - 使用 `@humansignal/ui` 包获取 UI 组件
  104. - 使用 `@humansignal/icons` 包获取图标
  105. - 使用 `@humansignal/core` 包获取核心工具/函数
  106. - 使用 `@humansignal/app-common` 包获取应用组件
  107. ## 最佳实践
  108. - 禁止循环导入
  109. - 使用适当的导入/导出
  110. - 遵循既定的导入顺序
  111. - 组合组件而非扩展组件
  112. - 保持组件专注于单一职责
  113. - 用清晰的注释记录复杂逻辑
  114. - 遵循项目的文件夹结构和命名约定
  115. - 优先使用受控组件而非非受控组件