react-debugging
Debug React components, fix hooks errors, resolve TypeScript issues, handle state management bugs, and fix rendering problems. Use when encountering React errors, hooks violations, type errors, or component rendering issues.
When & Why to Use This Skill
This Claude skill provides expert-level assistance for debugging React applications, specializing in fixing hook violations, TypeScript errors, and complex state management issues. It offers comprehensive solutions for common runtime exceptions, Next.js hydration mismatches, and performance bottlenecks like infinite render loops, ensuring robust and type-safe frontend development.
Use Cases
- Fixing runtime errors such as 'Cannot read property of undefined' or 'map is not a function' by implementing defensive programming and optional chaining.
- Resolving 'Rules of Hooks' violations, such as conditional hook calls, to ensure stable component lifecycles.
- Troubleshooting Next.js hydration failures by identifying and correcting discrepancies between server-side and client-side rendering.
- Debugging state management logic within Zustand stores or React Query caches to fix stale data and synchronization issues.
- Eliminating infinite re-render loops by optimizing useEffect dependency arrays and component memoization.
- Resolving complex TypeScript type mismatches and improving type inference for component props and API responses.
| name | react-debugging |
|---|---|
| description | Debug React components, fix hooks errors, resolve TypeScript issues, handle state management bugs, and fix rendering problems. Use when encountering React errors, hooks violations, type errors, or component rendering issues. |
| allowed-tools | Read, Edit, Grep, Glob, Bash |
React Component Debugging
Expert assistance for debugging React components and hooks in the MantisNXT Next.js project.
Capabilities
- Component Error Debugging: Fix runtime errors in React components
- Hooks Troubleshooting: Resolve issues with useState, useEffect, useQuery, etc.
- TypeScript Error Resolution: Fix type mismatches and inference issues
- State Management: Debug Zustand stores and React Query caches
- Rendering Issues: Fix hydration errors, infinite loops, and performance problems
Common Errors & Solutions
"X.map is not a function"
Cause: Variable expected to be an array is not an array (undefined, null, or object)
Solution:
// ❌ Unsafe
const items = data;
items.map(item => ...)
// ✅ Safe - ensure it's always an array
const items = Array.isArray(data) ? data : [];
items.map(item => ...)
// ✅ Alternative - provide default
const items = data || [];
const items = data ?? [];
"Cannot read property 'X' of undefined"
Cause: Accessing property on undefined/null object
Solution:
// ❌ Unsafe
const name = user.profile.name;
// ✅ Optional chaining
const name = user?.profile?.name;
// ✅ With default
const name = user?.profile?.name ?? 'Unknown';
"Rendered more hooks than during previous render"
Cause: Conditional hooks usage violates Rules of Hooks
Solution:
// ❌ Wrong - conditional hook
if (condition) {
const [state, setState] = useState(0);
}
// ✅ Correct - hook always called
const [state, setState] = useState(0);
if (condition) {
// use state here
}
"Hydration failed"
Cause: Server-rendered HTML doesn't match client render
Solution:
// ❌ Causes hydration mismatch
<div>{Math.random()}</div>
// ✅ Use client-only rendering
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null;
// ✅ Or mark component as client-side
'use client'
"Maximum update depth exceeded"
Cause: Infinite loop in useEffect or state updates
Solution:
// ❌ Wrong - infinite loop
useEffect(() => {
setState(newValue); // triggers re-render → triggers effect again
});
// ✅ Correct - proper dependencies
useEffect(() => {
setState(newValue);
}, [dependency]); // only runs when dependency changes
React Query Issues
Stale Data
// Force refetch
const { data, refetch } = useQuery(...);
refetch();
// Invalidate cache
queryClient.invalidateQueries(['key']);
// Set stale time
useQuery(['key'], fetcher, {
staleTime: 5 * 60 * 1000, // 5 minutes
});
Loading States
const { data, isLoading, error } = useQuery(...);
// ✅ Handle all states
if (isLoading) return <Loading />;
if (error) return <Error error={error} />;
if (!data) return <Empty />;
return <Content data={data} />;
Component File Locations
src/
├── components/
│ ├── dashboard/ # Dashboard components
│ ├── suppliers/ # Supplier management
│ ├── spp/ # Supplier pricelist processing
│ ├── layout/ # Layout components
│ └── ui/ # Shadcn UI components
├── hooks/
│ └── useNeonSpp.ts # React Query hooks
└── lib/
├── stores/ # Zustand stores
└── services/ # API services
Debugging Workflow
- Read the error message carefully - it often tells you exactly what's wrong
- Check the stack trace to find the exact line causing the issue
- Inspect the component where the error occurs
- Verify data types - ensure variables are what you expect (array vs object vs null)
- Check dependencies - verify useEffect/useCallback dependencies are correct
- Add console.logs strategically to track data flow
- Test incrementally - fix one issue at a time
Type Safety Best Practices
// ✅ Define proper interfaces
interface Upload {
upload_id: string;
filename: string;
status: string;
row_count: number;
}
// ✅ Type hook data
const { data } = useQuery<Upload[]>(...);
// ✅ Ensure array type
const uploads = Array.isArray(data) ? data : [];
// ✅ Type props
interface Props {
uploads: Upload[];
onRefresh: () => void;
}
Common Hook Patterns
Safe Data Fetching
const { data, isLoading, error } = useQuery(
['key'],
fetchFn,
{
staleTime: 5 * 60 * 1000,
retry: 3,
onError: (err) => console.error(err)
}
);
// Safely handle data
const items = Array.isArray(data) ? data : [];
Conditional Effects
useEffect(() => {
if (!condition) return; // early exit
// effect logic
return () => {
// cleanup
};
}, [condition]);
Memoization
// Expensive computation
const result = useMemo(() => {
return expensiveOperation(data);
}, [data]);
// Callback stability
const handleClick = useCallback(() => {
doSomething(value);
}, [value]);
Performance Optimization
- Use
React.memofor expensive components - Implement virtualization for long lists (react-window)
- Lazy load heavy components with
React.lazy - Debounce search inputs
- Optimize re-renders with proper dependency arrays
Testing Components
// Check component renders without errors
npm run dev
// Visit page in browser
// Type checking
npm run type-check
// Build check (catches many issues)
npm run build
Best Practices
- Always handle loading and error states
- Ensure data is the expected type before using array/object methods
- Follow Rules of Hooks - call hooks at top level, consistently
- Use TypeScript properly - don't use
any, define proper types - Add null checks for optional data
- Use optional chaining (?.) and nullish coalescing (??)
- Test edge cases - empty arrays, null values, loading states
- Keep components focused - single responsibility
- Extract custom hooks for reusable logic
- Clean up effects - return cleanup functions