react-code-review by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill react-code-review此技能为 React 应用程序提供结构化、全面的代码审查。它依据 React 19 最佳实践、组件架构模式、钩子使用、无障碍访问标准和生产就绪标准来评估代码。审查会生成按严重程度(关键、警告、建议)分类的可操作发现项,并提供具体的代码改进示例。
当通过代理系统调用时,此技能会委托 react-software-architect-review 代理进行深入的架构分析。
确定范围:确定需要审查哪些 React 组件和钩子。使用 glob 来发现 .tsx/.jsx 文件,并使用 grep 来识别组件定义、钩子使用和上下文提供者。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
分析组件架构:验证正确的组件组合——检查单一职责、适当的大小和可重用性。查找过大(>200 行)、props 过多(>7 个)或混合了不同关注点的组件。
审查钩子使用:验证钩子的正确使用——检查 useEffect/useMemo/useCallback 中的依赖数组,验证 useEffect 中的清理函数,并识别因缺少或不正确的记忆化导致的不必要重新渲染。
评估状态管理:评估状态存放的位置——检查是否进行了适当的共置,是否存在不必要的状态提升,以及是否正确使用了 Context 与外部存储。验证服务器状态是否使用了 TanStack Query、SWR 或类似的库,而不是手动的 useEffect + useState 模式。
检查无障碍访问:审查语义化 HTML 的使用、ARIA 属性、键盘导航、焦点管理和屏幕阅读器兼容性。验证交互元素是否可访问,表单输入是否有正确的标签。
评估性能:查找不必要的重新渲染、在开销大的组件上缺少 React.memo、useCallback/useMemo 使用不当、缺少代码分割以及大型包导入。
审查 TypeScript 集成:检查 prop 类型定义、事件处理程序类型、泛型组件模式以及工具类型的正确使用。验证在可能使用具体类型的地方是否没有使用 any。
生成审查报告:生成一份结构化的报告,包含按严重程度分类的发现项(关键、警告、建议)、积极的观察结果,以及带有代码示例的优先推荐建议。
// ❌ 不良:缺少依赖导致闭包过时
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, []); // 依赖数组中缺少 userId
return <div>{user?.name}</div>;
}
// ✅ 良好:具有清理功能的正确依赖
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
let cancelled = false;
fetchUser(userId).then((data) => {
if (!cancelled) setUser(data);
});
return () => { cancelled = true; };
}, [userId]);
return <div>{user?.name}</div>;
}
// ✅ 更好:使用 TanStack Query 处理服务器状态
function UserProfile({ userId }: { userId: string }) {
const { data: user, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
if (isLoading) return <Skeleton />;
return <div>{user?.name}</div>;
}
// ❌ 不良:混合了数据获取、过滤和渲染的单一庞大组件
function Dashboard() {
const [users, setUsers] = useState([]);
const [filter, setFilter] = useState('');
useEffect(() => { /* 在一个地方进行获取 + 过滤 + 排序 */ }, [filter]);
return <div>{/* 200+ 行混合关注点的代码 */}</div>;
}
// ✅ 良好:由专注的组件和自定义钩子组合而成
function Dashboard() {
return (
<div>
<UserFilters />
<Suspense fallback={<TableSkeleton />}>
<UserTable />
</Suspense>
<UserPagination />
</div>
);
}
// ❌ 不良:不可访问的交互元素
function Menu({ items }: { items: MenuItem[] }) {
const [open, setOpen] = useState(false);
return (
<div>
<div onClick={() => setOpen(!open)}>菜单</div>
{open && (
<div>
{items.map(item => (
<div key={item.id} onClick={() => navigate(item.path)}>
{item.label}
</div>
))}
</div>
)}
</div>
);
}
// ✅ 良好:具有正确语义和键盘支持的可访问组件
function Menu({ items }: { items: MenuItem[] }) {
const [open, setOpen] = useState(false);
return (
<nav aria-label="主导航">
<button
onClick={() => setOpen(!open)}
aria-expanded={open}
aria-controls="menu-list"
>
菜单
</button>
{open && (
<ul id="menu-list" role="menu">
{items.map(item => (
<li key={item.id} role="menuitem">
<a href={item.path}>{item.label}</a>
</li>
))}
</ul>
)}
</nav>
);
}
// ❌ 不良:每次渲染都重新创建的不稳定回调导致子组件重新渲染
{filtered.map(product => (
<ProductCard
key={product.id}
product={product}
onSelect={() => console.log(product.id)} // 每次渲染都创建新函数
/>
))}
// ✅ 良好:稳定的回调 + 记忆化的子组件
const handleSelect = useCallback((id: string) => {
console.log(id);
}, []);
const filtered = useMemo(
() => products.filter(p => p.name.toLowerCase().includes(search.toLowerCase())),
[products, search]
);
{filtered.map(product => (
<ProductCard key={product.id} product={product} onSelect={handleSelect} />
))}
const ProductCard = memo(function ProductCard({ product, onSelect }: Props) {
return <div onClick={() => onSelect(product.id)}>{product.name}</div>;
});
// ❌ 不良:松散的类型和缺失的 prop 定义
function Card({ data, onClick, children, ...rest }: any) {
return (
<div onClick={onClick} {...rest}>
<h2>{data.title}</h2>
{children}
</div>
);
}
// ✅ 良好:具有适当接口的严格类型
interface CardProps extends React.ComponentPropsWithoutRef<'article'> {
title: string;
description?: string;
variant?: 'default' | 'outlined' | 'elevated';
onAction?: (event: React.MouseEvent<HTMLButtonElement>) => void;
children: React.ReactNode;
}
function Card({
title,
description,
variant = 'default',
onAction,
children,
className,
...rest
}: CardProps) {
return (
<article className={cn('card', `card--${variant}`, className)} {...rest}>
<h2>{title}</h2>
{description && <p>{description}</p>}
{children}
{onAction && <button onClick={onAction}>操作</button>}
</article>
);
}
将所有代码审查发现项按以下结构组织:
简要概述,包含整体质量评分(1-10)和关键观察结果。
导致错误、安全漏洞或功能损坏的问题。
违反最佳实践、导致性能问题或降低可维护性的问题。
针对代码组织、无障碍访问或开发者体验的改进建议。
需要肯定的良好实现模式和优秀实践。
按优先级排序的后续步骤,包含对最具影响力改进的代码示例。
React.memouseEffect + useStateuseEffect 中包含清理函数any有关详细的审查清单和模式文档,请参阅 references/ 目录:
references/hooks-patterns.md — React 钩子最佳实践和常见错误references/component-architecture.md — 组件组合和设计模式references/accessibility.md — React 的无障碍访问清单和 ARIA 模式每周安装次数
131
仓库
GitHub 星标数
173
首次出现
2026年2月28日
安全审计
安装于
codex116
gemini-cli116
github-copilot114
kimi-cli111
amp111
opencode111
This skill provides structured, comprehensive code review for React applications. It evaluates code against React 19 best practices, component architecture patterns, hook usage, accessibility standards, and production-readiness criteria. The review produces actionable findings categorized by severity (Critical, Warning, Suggestion) with concrete code examples for improvements.
This skill delegates to the react-software-architect-review agent for deep architectural analysis when invoked through the agent system.
Identify Scope : Determine which React components and hooks are under review. Use glob to discover .tsx/.jsx files and grep to identify component definitions, hook usage, and context providers.
Analyze Component Architecture : Verify proper component composition — check for single responsibility, appropriate size, and reusability. Look for components that are too large (>200 lines), have too many props (>7), or mix concerns.
Review Hook Usage : Validate proper hook usage — check dependency arrays in useEffect/useMemo/useCallback, verify cleanup functions in useEffect, and identify unnecessary re-renders caused by missing or incorrect memoization.
Evaluate State Management : Assess where state lives — check for proper colocation, unnecessary lifting, and appropriate use of Context vs external stores. Verify that server state uses TanStack Query, SWR, or similar libraries rather than manual useEffect + useState patterns.
Check Accessibility : Review semantic HTML usage, ARIA attributes, keyboard navigation, focus management, and screen reader compatibility. Verify that interactive elements are accessible and form inputs have proper labels.
Assess Performance : Look for unnecessary re-renders, missing React.memo on expensive components, improper use of useCallback/useMemo, missing code splitting, and large bundle imports.
Review TypeScript Integration : Check prop type definitions, event handler typing, generic component patterns, and proper use of utility types. Verify that any is not used where specific types are possible.
Produce Review Report : Generate a structured report with severity-classified findings (Critical, Warning, Suggestion), positive observations, and prioritized recommendations with code examples.
// ❌ Bad: Missing dependency causes stale closure
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, []); // Missing userId in dependency array
return <div>{user?.name}</div>;
}
// ✅ Good: Proper dependencies with cleanup
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
let cancelled = false;
fetchUser(userId).then((data) => {
if (!cancelled) setUser(data);
});
return () => { cancelled = true; };
}, [userId]);
return <div>{user?.name}</div>;
}
// ✅ Better: Use TanStack Query for server state
function UserProfile({ userId }: { userId: string }) {
const { data: user, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
if (isLoading) return <Skeleton />;
return <div>{user?.name}</div>;
}
// ❌ Bad: Monolithic component mixing data fetching, filtering, and rendering
function Dashboard() {
const [users, setUsers] = useState([]);
const [filter, setFilter] = useState('');
useEffect(() => { /* fetch + filter + sort all in one */ }, [filter]);
return <div>{/* 200+ lines of mixed concerns */}</div>;
}
// ✅ Good: Composed from focused components with custom hooks
function Dashboard() {
return (
<div>
<UserFilters />
<Suspense fallback={<TableSkeleton />}>
<UserTable />
</Suspense>
<UserPagination />
</div>
);
}
// ❌ Bad: Inaccessible interactive elements
function Menu({ items }: { items: MenuItem[] }) {
const [open, setOpen] = useState(false);
return (
<div>
<div onClick={() => setOpen(!open)}>Menu</div>
{open && (
<div>
{items.map(item => (
<div key={item.id} onClick={() => navigate(item.path)}>
{item.label}
</div>
))}
</div>
)}
</div>
);
}
// ✅ Good: Accessible with proper semantics and keyboard support
function Menu({ items }: { items: MenuItem[] }) {
const [open, setOpen] = useState(false);
return (
<nav aria-label="Main navigation">
<button
onClick={() => setOpen(!open)}
aria-expanded={open}
aria-controls="menu-list"
>
Menu
</button>
{open && (
<ul id="menu-list" role="menu">
{items.map(item => (
<li key={item.id} role="menuitem">
<a href={item.path}>{item.label}</a>
</li>
))}
</ul>
)}
</nav>
);
}
// ❌ Bad: Unstable callback recreated every render causes child re-renders
{filtered.map(product => (
<ProductCard
key={product.id}
product={product}
onSelect={() => console.log(product.id)} // New function each render
/>
))}
// ✅ Good: Stable callback + memoized child
const handleSelect = useCallback((id: string) => {
console.log(id);
}, []);
const filtered = useMemo(
() => products.filter(p => p.name.toLowerCase().includes(search.toLowerCase())),
[products, search]
);
{filtered.map(product => (
<ProductCard key={product.id} product={product} onSelect={handleSelect} />
))}
const ProductCard = memo(function ProductCard({ product, onSelect }: Props) {
return <div onClick={() => onSelect(product.id)}>{product.name}</div>;
});
// ❌ Bad: Loose typing and missing prop definitions
function Card({ data, onClick, children, ...rest }: any) {
return (
<div onClick={onClick} {...rest}>
<h2>{data.title}</h2>
{children}
</div>
);
}
// ✅ Good: Strict typing with proper interfaces
interface CardProps extends React.ComponentPropsWithoutRef<'article'> {
title: string;
description?: string;
variant?: 'default' | 'outlined' | 'elevated';
onAction?: (event: React.MouseEvent<HTMLButtonElement>) => void;
children: React.ReactNode;
}
function Card({
title,
description,
variant = 'default',
onAction,
children,
className,
...rest
}: CardProps) {
return (
<article className={cn('card', `card--${variant}`, className)} {...rest}>
<h2>{title}</h2>
{description && <p>{description}</p>}
{children}
{onAction && <button onClick={onAction}>Action</button>}
</article>
);
}
Structure all code review findings as follows:
Brief overview with an overall quality score (1-10) and key observations.
Issues causing bugs, security vulnerabilities, or broken functionality.
Issues that violate best practices, cause performance problems, or reduce maintainability.
Improvements for code organization, accessibility, or developer experience.
Well-implemented patterns and good practices to acknowledge.
Prioritized next steps with code examples for the most impactful improvements.
React.memo only when measured re-render cost justifies ituseEffect + useStateuseEffect when subscribing to external resourcesany in component propsSee the references/ directory for detailed review checklists and pattern documentation:
references/hooks-patterns.md — React hooks best practices and common mistakesreferences/component-architecture.md — Component composition and design patternsreferences/accessibility.md — Accessibility checklist and ARIA patterns for ReactWeekly Installs
131
Repository
GitHub Stars
173
First Seen
Feb 28, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex116
gemini-cli116
github-copilot114
kimi-cli111
amp111
opencode111
Tailwind CSS v4 + shadcn/ui 生产级技术栈配置指南与最佳实践
2,600 周安装