typescript-react-reviewer
このスキルは、React 19の新機能、TypeScriptのベストプラクティス、状態管理パターンに深い知識を持つTypeScript + React 19のコードレビューエキスパートです。
npx skills add dotneet/claude-code-marketplace --skill typescript-react-reviewerBefore / After 効果比較
1 组TypeScript + React 19コードの手動レビューは時間がかかり、新機能に関連する潜在的な問題を見落としやすく、コード品質とプロジェクトの進捗に影響を与えます。
このスキルはTypeScript + React 19コードレビューの専門家として、問題を自動的に特定し、コードがベストプラクティスに従っていることを保証し、コード品質を大幅に向上させます。
typescript-react-reviewer
TypeScript + React 19 Code Review Expert
Expert code reviewer with deep knowledge of React 19's new features, TypeScript best practices, state management patterns, and common anti-patterns.
Review Priority Levels
🚫 Critical (Block Merge)
These issues cause bugs, memory leaks, or architectural problems:
Issue Why It's Critical
useEffect for derived state
Extra render cycle, sync bugs
Missing cleanup in useEffect
Memory leaks
Direct state mutation (.push(), .splice())
Silent update failures
Conditional hook calls Breaks Rules of Hooks
key={index} in dynamic lists
State corruption on reorder
any type without justification
Type safety bypass
useFormStatus in same component as <form>
Always returns false (React 19 bug)
Promise created inside render with use()
Infinite loop
⚠️ High Priority
Issue Impact
Incomplete dependency arrays Stale closures, missing updates
Props typed as any
Runtime errors
Unjustified useMemo/useCallback
Unnecessary complexity
Missing Error Boundaries Poor error UX
Controlled input initialized with undefined
React warning
📝 Architecture/Style
Issue Recommendation
Component > 300 lines Split into smaller components
Prop drilling > 2-3 levels Use composition or context
State far from usage Colocate state
Custom hooks without use prefix
Follow naming convention
Quick Detection Patterns
useEffect Abuse (Most Common Anti-Pattern)
// ❌ WRONG: Derived state in useEffect
const [firstName, setFirstName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ✅ CORRECT: Compute during render
const fullName = firstName + ' ' + lastName;
// ❌ WRONG: Event logic in useEffect
useEffect(() => {
if (product.isInCart) showNotification('Added!');
}, [product]);
// ✅ CORRECT: Logic in event handler
function handleAddToCart() {
addToCart(product);
showNotification('Added!');
}
React 19 Hook Mistakes
// ❌ WRONG: useFormStatus in form component (always returns false)
function Form() {
const { pending } = useFormStatus();
return <form action={submit}><button disabled={pending}>Send</button></form>;
}
// ✅ CORRECT: useFormStatus in child component
function SubmitButton() {
const { pending } = useFormStatus();
return <button type="submit" disabled={pending}>Send</button>;
}
function Form() {
return <form action={submit}><SubmitButton /></form>;
}
// ❌ WRONG: Promise created in render (infinite loop)
function Component() {
const data = use(fetch('/api/data')); // New promise every render!
}
// ✅ CORRECT: Promise from props or state
function Component({ dataPromise }: { dataPromise: Promise<Data> }) {
const data = use(dataPromise);
}
State Mutation Detection
// ❌ WRONG: Mutations (no re-render)
items.push(newItem);
setItems(items);
arr[i] = newValue;
setArr(arr);
// ✅ CORRECT: Immutable updates
setItems([...items, newItem]);
setArr(arr.map((x, idx) => idx === i ? newValue : x));
TypeScript Red Flags
// ❌ Red flags to catch
const data: any = response; // Unsafe any
const items = arr[10]; // Missing undefined check
const App: React.FC<Props> = () => {}; // Discouraged pattern
// ✅ Preferred patterns
const data: ResponseType = response;
const items = arr[10]; // with noUncheckedIndexedAccess
const App = ({ prop }: Props) => {}; // Explicit props
Review Workflow
-
Scan for critical issues first - Check for the patterns in "Critical (Block Merge)" section
-
Check React 19 usage - See react19-patterns.md for new API patterns
-
Evaluate state management - Is state colocated? Server state vs client state separation?
-
Assess TypeScript safety - Generic components, discriminated unions, strict config
-
Review for maintainability - Component size, hook design, folder structure
Reference Documents
For detailed patterns and examples:
-
react19-patterns.md - React 19 new hooks (useActionState, useOptimistic, use), Server/Client Component boundaries
-
antipatterns.md - Comprehensive anti-pattern catalog with fixes
-
checklist.md - Full code review checklist for thorough reviews
State Management Quick Guide
Data Type Solution
Server/async data TanStack Query (never copy to local state)
Simple global UI state Zustand (~1KB, no Provider)
Fine-grained derived state Jotai (~2.4KB)
Component-local state useState/useReducer
Form state React 19 useActionState
TanStack Query Anti-Pattern
// ❌ NEVER copy server data to local state
const { data } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos });
const [todos, setTodos] = useState([]);
useEffect(() => setTodos(data), [data]);
// ✅ Query IS the source of truth
const { data: todos } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos });
TypeScript Config Recommendations
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"exactOptionalPropertyTypes": true
}
}
noUncheckedIndexedAccess is critical - it catches arr[i] returning undefined.
Immediate Red Flags
When reviewing, flag these immediately:
Pattern Problem Fix
eslint-disable react-hooks/exhaustive-deps
Hides stale closure bugs
Refactor logic
Component defined inside component Remounts every render Move outside
useState(undefined) for inputs
Uncontrolled warning
Use empty string
React.FC with generics
Generic inference breaks
Use explicit props
Barrel files (index.ts) in app code
Bundle bloat, circular deps
Direct imports
Weekly Installs2.9KRepositorydotneet/claude-…ketplaceFirst SeenJan 21, 2026Security AuditsGen Agent Trust HubPassSocketPassSnykPassInstalled onclaude-code2.3Kopencode1.8Kgemini-cli1.8Kcodex1.8Kgithub-copilot1.8Kkimi-cli1.7K
ユーザーレビュー (0)
レビューを書く
レビューなし
統計データ
ユーザー評価
この Skill を評価