typescript-react-reviewer

TypeScript + React 19 Code Review Expert

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "typescript-react-reviewer" with this command: npx skills add dotneet/claude-code-marketplace/dotneet-claude-code-marketplace-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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-modularization-evaluator

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

prompt-improver

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

call-cursor-agent

No summary provided by upstream source.

Repository SourceNeeds Review