React Core Knowledge
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: react for comprehensive documentation on hooks, components, and React patterns.
Component Patterns
Functional Components (Preferred)
function UserCard({ name, email }: UserCardProps) {
return (
<div className="card">
<h2>{name}</h2>
<p>{email}</p>
</div>
);
}
Props Typing
interface Props {
title: string;
count?: number;
children: React.ReactNode;
onClick: (id: string) => void;
}
Essential Hooks
| Hook |
Purpose |
useState |
Local state |
useEffect |
Side effects, subscriptions |
useContext |
Access context values |
useRef |
DOM refs, mutable values |
useMemo |
Memoize expensive computations |
useCallback |
Memoize functions |
useReducer |
Complex state logic |
Key Patterns
- Composition over inheritance
- Lift state up for shared state
- Props drilling → use Context or state library
- Controlled vs Uncontrolled inputs
Performance
- Use
React.memo() for expensive pure components
- Memoize with
useMemo/useCallback only when needed
- Use
key prop correctly in lists
- Lazy load with
React.lazy() + Suspense
Production Readiness
Security Best Practices
// NEVER use dangerouslySetInnerHTML with user input
// BAD
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// GOOD - Sanitize with DOMPurify
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
// Avoid exposing sensitive data in client-side state
// BAD
const [apiKey, setApiKey] = useState(process.env.API_KEY);
// GOOD - API keys should stay server-side
// Use API routes or server actions instead
// Validate all external URLs
const isValidUrl = (url: string) => {
try {
const parsed = new URL(url);
return ['http:', 'https:'].includes(parsed.protocol);
} catch {
return false;
}
};
Error Boundaries
import { ErrorBoundary } from 'react-error-boundary';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button again</button>
</div>
);
}
// Usage
<ErrorBoundary
FallbackComponent={ErrorFallback}
=> window.location.reload()}
info) => {
// Log to error reporting service
logErrorToService(error, info);
}}
>
<App />
</ErrorBoundary>
Performance Optimization
// Code splitting with lazy loading
const Dashboard = lazy(() => import('./Dashboard'));
function App() {
return (
<Suspense fallback={<Skeleton />}>
<Dashboard />
</Suspense>
);
}
// Memoization - use sparingly, only for expensive components
const ExpensiveList = memo(function ExpensiveList({ items }: Props) {
return items.map(item => <ExpensiveItem key={item.id} {...item} />);
});
// Virtualization for large lists
import { FixedSizeList } from 'react-window';
function VirtualList({ items }: { items: Item[] }) {
return (
<FixedSizeList
height={400}
itemCount={items.length}
itemSize={50}
width="100%"
>
{({ index, style }) => (
<div style={style}>{items[index].name}</div>
)}
</FixedSizeList>
);
}
Accessibility (a11y)
// Use semantic HTML
<button // NOT <div onClick>
// ARIA labels for icons/images
<button aria-label="Close dialog"
<XIcon />
</button>
// Focus management
const dialogRef = useRef<HTMLDivElement>(null);
useEffect(() => {
dialogRef.current?.focus();
}, [isOpen]);
// Keyboard navigation
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
if (e.key === 'Tab') trapFocus(e);
};
Testing Setup
// Component testing with Testing Library
import { render, screen, userEvent } from '@testing-library/react';
test('submits form with user data', async () => {
const
render(<Form />);
await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
await userEvent.click(screen.getByRole('button', { name: /submit/i }));
expect(onSubmit).toHaveBeenCalledWith({ email: 'test@example.com' });
});
Monitoring Metrics
| Metric |
Alert Threshold |
| Largest Contentful Paint (LCP) |
> 2.5s |
| First Input Delay (FID) |
> 100ms |
| Cumulative Layout Shift (CLS) |
> 0.1 |
| JavaScript bundle size |
> 200KB (gzipped) |
| Component render time |
> 16ms |
Build & Bundle Optimization
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
ui: ['@radix-ui/react-dialog', '@radix-ui/react-dropdown'],
},
},
},
sourcemap: true, // For error tracking in production
},
});
Checklist
When NOT to Use This Skill
- React 19 specific features (Actions, useActionState, use()) - Use
react-19 skill instead
- Advanced performance optimization - Use
react-performance skill instead
- Form handling patterns - Use
react-forms or react-hook-form skills instead
- Routing - Use
react-router skill instead
- Testing - Use
react-testing skill instead
- Component design patterns - Use
react-patterns skill instead
Anti-Patterns
| Anti-Pattern |
Problem |
Solution |
| Mutating state directly |
Doesn't trigger re-render |
Use setState with new object/array |
| Missing dependency arrays |
Stale closures, memory leaks |
Include all dependencies or use ESLint |
| useEffect for derived state |
Extra re-renders |
Calculate during render or use useMemo |
| Props drilling deeply |
Hard to maintain |
Use Context or state library |
| Inline object/array in JSX |
Breaks memoization |
Extract to constant or useMemo |
| New functions in render |
Child re-renders unnecessarily |
Use useCallback |
| Forgetting cleanup in useEffect |
Memory leaks |
Return cleanup function |
| Using index as key |
Incorrect re-renders |
Use stable unique ID |
Quick Troubleshooting
| Issue |
Likely Cause |
Fix |
| Component not re-rendering |
State mutation |
Use setState with new reference |
| Infinite loop in useEffect |
Missing/wrong dependencies |
Add deps or use functional update |
| "Cannot read property of undefined" |
Async data not loaded |
Add null checks or loading state |
| Memory leak warning |
Missing cleanup |
Return cleanup function from useEffect |
| Children not updating |
Using index as key |
Use unique stable ID |
| Handler not firing |
Event propagation stopped |
Check stopPropagation() calls |
| Stale state in callback |
Closure over old state |
Use functional setState |
Reference Documentation
- Hooks Cheatsheet
- Component Patterns
- Deep: Hooks Guide
- Deep: Performance