Smart React Best Practices Kit
All-in-one skill for managing react patterns, hooks, and performance optimization. Built for Claude Code with best practices and real-world patterns.
React Best Practices Kit
Comprehensive React development best practices guide covering component architecture, state management, performance optimization, testing strategies, and modern React patterns for production applications.
When to Use This Skill
Choose React Best Practices when:
- Starting a new React project and need architectural guidance
- Refactoring existing components for better maintainability
- Reviewing code for React anti-patterns and performance issues
- Establishing team coding standards for React development
- Migrating from class components to modern hooks-based patterns
Consider alternatives when:
- Building with a different framework — use Vue, Svelte, or Angular guides
- Need UI components — use a component library (Shadcn, Radix, MUI)
- Need backend architecture — use backend-specific patterns
Quick Start
# Activate React best practices claude skill activate smart-react-best-practices-kit # Review component architecture claude "Review my React components for best practices violations" # Optimize performance claude "Identify performance issues in the Dashboard component"
Example: Well-Structured Component
// Good: Single responsibility, typed props, clear data flow interface UserCardProps { user: User; onEdit: (userId: string) => void; variant?: 'compact' | 'full'; } export function UserCard({ user, onEdit, variant = 'compact' }: UserCardProps) { const formattedDate = useMemo( () => formatDate(user.joinedAt), [user.joinedAt] ); const handleEdit = useCallback(() => { onEdit(user.id); }, [onEdit, user.id]); return ( <article className={cn('user-card', `user-card--${variant}`)}> <Avatar src={user.avatar} alt={user.name} /> <div> <h3>{user.name}</h3> <p>Joined {formattedDate}</p> </div> <button onClick={handleEdit} aria-label={`Edit ${user.name}`}> Edit </button> </article> ); }
Core Concepts
Component Design Principles
| Principle | Description | Example |
|---|---|---|
| Single Responsibility | Each component does one thing well | UserAvatar vs UserProfileDashboardWithSettings |
| Composition over Inheritance | Build complex UIs from small, composable pieces | <Card><CardHeader /><CardBody /></Card> |
| Controlled Components | Parent owns the state, child renders it | Form inputs with value + onChange |
| Colocation | Keep related code close together | Styles, tests, types next to component |
| Lifting State | Share state by moving it to the nearest common ancestor | Sibling components sharing filter state |
Performance Patterns
| Pattern | When to Use | Implementation |
|---|---|---|
React.memo | Component re-renders with same props | export default memo(ExpensiveList) |
useMemo | Expensive computations that depend on specific values | useMemo(() => sort(items), [items]) |
useCallback | Function props passed to memoized children | useCallback(() => save(id), [id]) |
| Virtualization | Long lists (>100 items) | react-window or @tanstack/virtual |
| Code Splitting | Large components not needed immediately | lazy(() => import('./HeavyChart')) |
| Suspense | Loading states for async data/components | <Suspense fallback={<Spinner />}> |
// State management decision tree // Local UI state → useState const [isOpen, setIsOpen] = useState(false); // Complex local state → useReducer const [state, dispatch] = useReducer(formReducer, initialState); // Shared state (few consumers) → Context const ThemeContext = createContext<Theme>(defaultTheme); // Server state → TanStack Query const { data, isLoading } = useQuery({ queryKey: ['users'], queryFn: fetchUsers, }); // Complex global state → Zustand (or Redux for large apps) const useStore = create<AppStore>((set) => ({ cart: [], addItem: (item) => set((s) => ({ cart: [...s.cart, item] })), }));
Configuration
| Parameter | Description | Default |
|---|---|---|
strict_mode | Enable React Strict Mode checks | true |
state_management | Preferred: context, zustand, redux, jotai | zustand |
styling | Approach: tailwind, css-modules, styled-components | tailwind |
testing_framework | Testing: vitest, jest | vitest |
file_structure | Organization: feature-based, type-based | feature-based |
error_boundaries | Require error boundaries per route | true |
Best Practices
-
Use TypeScript with strict mode for all React projects — TypeScript catches prop mismatches, missing handlers, and type errors at build time. Enable
strict: truein tsconfig and define explicit interfaces for all component props. -
Colocate related files by feature, not by type — Group component, styles, tests, and types in the same directory rather than separating into
components/,styles/,tests/folders. This makes features self-contained and easier to move, delete, or refactor. -
Avoid premature memoization — measure first — Don't wrap every component in
React.memoor every function inuseCallback. Use React DevTools Profiler to identify actual re-render bottlenecks. Memoization has its own cost and adds complexity. -
Use TanStack Query (React Query) for all server state — Stop using
useEffect+useStatefor data fetching. TanStack Query handles caching, deduplication, background refetching, and loading/error states out of the box with significantly less code. -
Keep components under 150 lines — extract when they grow — If a component exceeds 150 lines, it likely has multiple responsibilities. Extract custom hooks for logic, child components for UI sections, and utility functions for data transformation.
Common Issues
Components re-render too frequently, causing performance problems. Use React DevTools Profiler to identify which components re-render and why. Common causes: creating new objects/arrays in render (use useMemo), inline function definitions passed as props (use useCallback), and context providers with object values that create new references on every render.
State updates don't reflect immediately after calling setState. React state updates are asynchronous and batched. Don't read state immediately after setting it — use the functional updater form setState(prev => prev + 1) when the new value depends on the previous one, and use useEffect to react to state changes.
useEffect runs in an infinite loop. This happens when the effect modifies a value in its own dependency array. Review dependencies to ensure they're stable references. Move object/array creation inside the effect or memoize with useMemo. If the dependency is a function from a parent, ask the parent to wrap it in useCallback.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.