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
; }// ✅ CORRECT: useFormStatus in child component function SubmitButton() { const { pending } = useFormStatus(); return ; } function Form() { return
; }// ❌ 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 }) { 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
// ✅ 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