mcpField
G
generic-react-code-reviewer

generic-react-code-reviewer

github.com/travisjneuman测试与质量106143 次安装1 天前更新
代码仓库

关于 generic-react-code-reviewer

面向 React 和 TypeScript 开发者的代码审查技能,用于按生产质量标准检查代码。它聚焦类型安全、组件与状态管理、性能和无障碍,并建议通过阅读 diff 进行验证。

主要功能

  1. 01TypeScript 严格模式检查
  2. 02组件与 Hook 依赖检查
  3. 03状态管理类型检查
  4. 04查询缓存与错误处理检查
  5. 05性能与无障碍审查

适用场景

  1. 01提交 React 代码前检查 diff
  2. 02检查 Hook 依赖和状态类型
  3. 03审查懒加载、缓存及焦点管理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/travisjneuman/.claude --skill generic-react-code-reviewer

安装后在 Claude Code 中输入/generic-react-code-reviewer确认已加载。

详细介绍

React 代码审查员

根据生产环境质量标准审查 React/TypeScript 代码。

扩展: 通用代码审查员——阅读基础技能,了解完整的代码审查方法、P0/P1/P2 优先级系统以及判断标准。

提交前验证

通过阅读差异进行验证,而不是按顺序运行测试、lint 和构建;以下内容是需要检查的项目。

React 专项检查

TypeScript 严格模式
// Required tsconfig.json settings
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}
  • 用户输入或 API 响应不得使用 any 类型
  • 先用 unknown 接收外部数据,再通过类型守卫验证
  • 可复用工具中优先使用泛型,而不是 any
组件模式
模式检查项
Props已定义接口,不使用 any
State使用 Zustand/useState 定义类型
Events事件处理函数已定义类型
RefsuseRef<ElementType>(null)
Hook 依赖数组
// P1 Issue: Missing dependencies
useEffect(() => {
  fetchData(userId); // userId missing from deps
}, []); // ❌

// Correct
useEffect(() => {
  fetchData(userId);
}, [userId]); // ✓

规则: 启用 react-hooks/exhaustive-deps ESLint 规则。

状态管理(Zustand/Redux)
  • Store 切片已正确定义类型
  • Actions 返回 void(直接更新状态)
  • 派生状态的选择器已进行记忆化
  • 大型数据(>1MB)存入 IndexedDB,而非 localStorage
React Query/SWR 模式
// Proper typing
const { data } = useQuery<User>({
  queryKey: ["user", id],
  queryFn: () => fetchUser(id),
});

// Check: staleTime, cacheTime configured
// Check: error boundaries for query failures

性能(P1)

包体积目标
目标阈值
初始包体积< 100KB(gzip 压缩后)
懒加载分块每个 < 50KB
JS 总量< 300KB
懒加载
// Heavy components (>20KB) MUST be lazy loaded
const HeavyChart = lazy(() => import('./HeavyChart'));
const RichTextEditor = lazy(() => import('./RichTextEditor'));

// Wrap in Suspense
<Suspense fallback={<Skeleton />}>
  <HeavyChart />
</Suspense>
记忆化
// Expensive calculations
const sortedItems = useMemo(() =>
  items.sort((a, b) => a.date - b.date),
  [items]
);

// Callback stability for child components
const handleClick = useCallback(() => {
  doSomething(id);
}, [id]);

// Component memoization (when props are stable)
export const Item = memo(function Item({ data }: Props) {
  return <div>{data.name}</div>;
});
动画(仅限 GPU 加速)
/* ✓ DO animate */
transform: translateY(-4px);
opacity: 0.5;

/* ❌ NEVER animate */
width, height, margin, padding, top, left

无障碍访问(P1)

焦点管理
// Modal focus trapping
useEffect(() => {
  if (isOpen) {
    const firstFocusable = modalRef.current?.querySelector("button, input");
    firstFocusable?.focus();
  }
}, [isOpen]);

// Escape to close
useEffect(() => {
  const handleEscape = (e: KeyboardEvent) => {
    if (e.key === "Escape") onClose();
  };
  window.addEventListener("keydown", handleEscape);
  return () => window.removeEventListener("keydown", handleEscape);
}, [onClose]);
JSX 中的 ARIA
// Icon-only buttons require labels
<button aria-label="Close modal">
  <X className="w-5 h-5" />
</button>

// Dialogs
<div role="dialog" aria-modal="true" aria-labelledby="title">
  <h2 id="title">Confirm Action</h2>
</div>

快速审查清单

React 专项(添加到基础清单):

  • Hook 依赖项正确
  • 重型组件已懒加载
  • 状态管理已定义类型
  • 在有益的地方使用记忆化
  • 模态框中已管理焦点

另请参阅

评论

支持 Markdown