--- name: developing-with-react description: React 18+ development with hooks, state management, component patterns, and Next.js integration. Use when building React applications or working with JSX/TSX components. --- # React Framework - Quick Reference **Version**: 1.0.0 | **Framework**: React 18+ | **Use Case**: Fast lookups during active development --- ## When to Use Load this skill when: - `package.json` contains `"react"` dependency (>=18.0.0) - Project has `.jsx` or `.tsx` files in `src/` - Next.js, Vite, or Create React App detected - User mentions "React" in task description **Minimum Detection Confidence**: 0.8 (80%) --- ## Quick Start ```tsx import { FC, useState } from 'react'; interface Props { title: string; onAction?: () => void; } export const MyComponent: FC = ({ title, onAction }) => { const [count, setCount] = useState(0); return (

{title}

Count: {count}

); }; ``` --- ## Component Design ### Functional Component Structure ```tsx // 1. Imports (grouped and sorted) import { useState, useEffect } from 'react'; import type { FC, ReactNode } from 'react'; // 2. Types/Interfaces interface Props { children: ReactNode; className?: string; } // 3. Component export const Component: FC = ({ children, className }) => { // 4. Hooks (state, effects, context) const [state, setState] = useState(''); useEffect(() => { // Side effects }, []); // 5. Event handlers const handleClick = () => setState('clicked'); // 6. Early returns (error states, loading) if (!children) return null; // 7. Main render return
{children}
; }; ``` ### Container/Presentational Pattern ```tsx // Container: Logic and data fetching export const UserProfileContainer: FC<{ userId: number }> = ({ userId }) => { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch(`/api/users/${userId}`) .then(res => res.json()) .then(setUser) .finally(() => setLoading(false)); }, [userId]); if (loading) return ; if (!user) return ; return ; }; // Presentational: Pure UI export const UserProfile: FC<{ user: User }> = ({ user }) => (

{user.name}

{user.email}

); ``` --- ## Core Hooks ### useState - Local State ```tsx // Basic usage const [count, setCount] = useState(0); const [user, setUser] = useState(null); // Functional updates (when new state depends on old) setCount(prevCount => prevCount + 1); // Lazy initialization (expensive computation) const [data, setData] = useState(() => expensiveComputation()); // Object state updates (always spread) setForm(prev => ({ ...prev, email: 'new@email.com' })); ``` ### useEffect - Side Effects ```tsx // Run once on mount useEffect(() => { fetchData(); }, []); // Run when dependencies change useEffect(() => { fetchUser(userId); }, [userId]); // Cleanup function useEffect(() => { const subscription = api.subscribe(); return () => subscription.unsubscribe(); }, []); // Abort fetch on unmount useEffect(() => { const controller = new AbortController(); fetch(url, { signal: controller.signal }); return () => controller.abort(); }, [url]); ``` ### useContext - Consume Context ```tsx interface ThemeContextType { theme: 'light' | 'dark'; toggleTheme: () => void; } const ThemeContext = createContext(undefined); // Provider export const ThemeProvider: FC<{ children: ReactNode }> = ({ children }) => { const [theme, setTheme] = useState<'light' | 'dark'>('light'); const toggleTheme = () => setTheme(prev => prev === 'light' ? 'dark' : 'light'); return ( {children} ); }; // Custom hook (always validate context exists) export const useTheme = () => { const context = useContext(ThemeContext); if (!context) throw new Error('useTheme must be used within ThemeProvider'); return context; }; ``` ### useReducer - Complex State ```tsx type Action = { type: 'increment' } | { type: 'decrement' } | { type: 'reset' }; const reducer = (state: number, action: Action): number => { switch (action.type) { case 'increment': return state + 1; case 'decrement': return state - 1; case 'reset': return 0; default: return state; } }; const Counter = () => { const [count, dispatch] = useReducer(reducer, 0); return (

Count: {count}

); }; ``` ### Custom Hooks ```tsx function useFetch(url: string) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const controller = new AbortController(); fetch(url, { signal: controller.signal }) .then(res => res.json()) .then(setData) .catch(setError) .finally(() => setLoading(false)); return () => controller.abort(); }, [url]); return { data, loading, error }; } // Usage const { data: user, loading, error } = useFetch(`/api/users/${userId}`); ``` --- ## Performance Optimization ### React.memo - Prevent Re-renders ```tsx // Memoize component - only re-renders when props change export const ExpensiveComponent = memo(({ data }: { data: Data }) => { return
{/* expensive rendering */}
; }); // With custom comparison export const CustomMemo = memo( ({ user }: { user: User }) =>
{user.name}
, (prev, next) => prev.user.id === next.user.id ); ``` ### useMemo & useCallback ```tsx // useMemo: Memoize expensive computations const filteredItems = useMemo(() => { return items.filter(item => item.includes(filter)); }, [items, filter]); // useCallback: Memoize function references const handleClick = useCallback(() => { setCount(c => c + 1); }, []); // Pass to memoized children to prevent re-renders ``` ### Code Splitting ```tsx import { lazy, Suspense } from 'react'; const HeavyComponent = lazy(() => import('./HeavyComponent')); const App = () => ( Loading...}> ); ``` --- ## Accessibility (WCAG 2.1 AA) ### Essential Patterns ```tsx // Use semantic HTML // Good
Click me
// Bad // ARIA labels for screen readers // ARIA descriptions We'll never share your email // Live regions for dynamic content
{statusMessage}
// Keyboard navigation const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); if (e.key === 'Enter') onSubmit(); }; ``` ### Form Accessibility ```tsx
{errors.email && {errors.email}}
``` --- ## TypeScript Quick Reference ### Component Props ```tsx interface Props { title: string; // Required subtitle?: string; // Optional variant: 'primary' | 'secondary'; // Union types onClick?: () => void; // Optional function onSubmit: (data: FormData) => void; // Required function children: ReactNode; // Children user: User; // Complex type } export const Component: FC = ({ title, onClick }) => (
{title}
); ``` ### Event Handlers ```tsx const handleClick = (e: MouseEvent) => {}; const handleChange = (e: ChangeEvent) => {}; const handleSubmit = (e: FormEvent) => { e.preventDefault(); }; const handleKeyDown = (e: KeyboardEvent) => {}; ``` ### Refs ```tsx const inputRef = useRef(null); useEffect(() => { inputRef.current?.focus(); }, []); ``` --- ## Anti-Patterns (Avoid These) ```tsx // DON'T: Mutate state directly user.name = 'Jane'; setUser(user); // Bad setUser({ ...user, name: 'Jane' }); // Good // DON'T: Use index as key {items.map((item, i) =>
{item}
)} // Bad {items.map(item =>
{item}
)} // Good // DON'T: Call hooks conditionally if (condition) { useState(0); } // Bad - hooks must be top-level // DON'T: Miss useEffect dependencies useEffect(() => { fetchUser(userId); }, []); // Bad useEffect(() => { fetchUser(userId); }, [userId]); // Good // DON'T: Inline functions in JSX (when performance matters) // Bad // Good (with useCallback) ``` --- ## Testing Quick Reference ```tsx import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { axe, toHaveNoViolations } from 'jest-axe'; expect.extend(toHaveNoViolations); describe('Button', () => { it('renders with text', () => { render(); expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument(); }); it('handles click events', async () => { const handleClick = jest.fn(); render(); await userEvent.click(screen.getByRole('button')); expect(handleClick).toHaveBeenCalledTimes(1); }); it('has no accessibility violations', async () => { const { container } = render(); expect(await axe(container)).toHaveNoViolations(); }); }); ``` --- ## Integration Checklist When using this skill, ensure: - [ ] Components use TypeScript with strict types - [ ] Interactive elements are keyboard accessible - [ ] ARIA attributes added where semantic HTML insufficient - [ ] Performance optimization applied (memo, useMemo, useCallback) - [ ] Unit tests written with React Testing Library - [ ] Accessibility tests with jest-axe - [ ] Custom hooks extracted for reusable logic - [ ] Error boundaries implemented for error handling --- ## See Also - **[REFERENCE.md](REFERENCE.md)** - Comprehensive React guide with: - Advanced component patterns (compound components, render props, HOCs) - Complete hooks deep dive - State management architectures (Context optimization, Redux, Zustand) - Full WCAG 2.1 AA accessibility guide - Performance profiling and optimization - Testing strategies and patterns - TypeScript advanced patterns - Styling approaches (CSS Modules, styled-components, Tailwind) - **[templates/](templates/)** - Code generation templates - **[examples/](examples/)** - Real-world implementation examples --- **Version**: 1.0.0 | **Last Updated**: 2025-01-01 | **Status**: Production Ready