S

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.

SkillCommunityfrontendv1.0.0MIT
0 views0 copies

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

PrincipleDescriptionExample
Single ResponsibilityEach component does one thing wellUserAvatar vs UserProfileDashboardWithSettings
Composition over InheritanceBuild complex UIs from small, composable pieces<Card><CardHeader /><CardBody /></Card>
Controlled ComponentsParent owns the state, child renders itForm inputs with value + onChange
ColocationKeep related code close togetherStyles, tests, types next to component
Lifting StateShare state by moving it to the nearest common ancestorSibling components sharing filter state

Performance Patterns

PatternWhen to UseImplementation
React.memoComponent re-renders with same propsexport default memo(ExpensiveList)
useMemoExpensive computations that depend on specific valuesuseMemo(() => sort(items), [items])
useCallbackFunction props passed to memoized childrenuseCallback(() => save(id), [id])
VirtualizationLong lists (>100 items)react-window or @tanstack/virtual
Code SplittingLarge components not needed immediatelylazy(() => import('./HeavyChart'))
SuspenseLoading 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

ParameterDescriptionDefault
strict_modeEnable React Strict Mode checkstrue
state_managementPreferred: context, zustand, redux, jotaizustand
stylingApproach: tailwind, css-modules, styled-componentstailwind
testing_frameworkTesting: vitest, jestvitest
file_structureOrganization: feature-based, type-basedfeature-based
error_boundariesRequire error boundaries per routetrue

Best Practices

  1. Use TypeScript with strict mode for all React projects — TypeScript catches prop mismatches, missing handlers, and type errors at build time. Enable strict: true in tsconfig and define explicit interfaces for all component props.

  2. 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.

  3. Avoid premature memoization — measure first — Don't wrap every component in React.memo or every function in useCallback. Use React DevTools Profiler to identify actual re-render bottlenecks. Memoization has its own cost and adds complexity.

  4. Use TanStack Query (React Query) for all server state — Stop using useEffect + useState for data fetching. TanStack Query handles caching, deduplication, background refetching, and loading/error states out of the box with significantly less code.

  5. 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.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates