React

Design Patterns That Transformed My React Code

A collection of React patterns I use daily: Compound Components, Custom Hooks, State Machines, and more. Practical examples from real projects.

3 min read
ReactDesign PatternsTypeScriptFrontendArchitecture
Design Patterns That Transformed My React Code

Beyond Basic React

Writing React components is easy. Writing React components that scale, that other developers understand instantly, and that don't become maintenance nightmares—that's an art. These patterns have transformed how I build applications.

1. Compound Components

This pattern changed everything for me. Instead of passing dozens of props to configure a component, you compose it from smaller pieces. Think of how HTML's <select> and <option> work together.

The Power

  • Flexible composition without prop drilling
  • Clear, declarative APIs
  • Each piece is independently testable
  • Users control the layout

I use this pattern for Tabs, Accordions, Dropdown menus, and any component where users need control over structure.

2. Custom Hooks: Extract Everything

If you're not writing custom hooks, you're missing React's most powerful feature. Any stateful logic that could be reused should become a hook.

My Rules for Hooks

  • One responsibility per hook
  • Return tuples for simple state, objects for complex
  • Handle loading and error states consistently
  • Document the expected behavior

Hooks I Write for Every Project

  • useLocalStorage: Persistent state that syncs across tabs
  • useDebounce: Delay expensive operations
  • useMediaQuery: Responsive logic in JavaScript
  • useOnClickOutside: Close modals and dropdowns properly

3. State Machines for Complex UI

When your component has more than three states, reach for a state machine. They make impossible states impossible and complex flows understandable.

A login form isn't just "loading" or "not loading". It's idle, validating, submitting, succeeded, or failed. Each state has specific allowed transitions. State machines encode this explicitly.

4. Render Props (Still Useful)

Hooks have replaced most render prop use cases, but the pattern still shines for components that need to share DOM-related state—like mouse position or scroll position.

5. Provider Pattern for Global State

Context API gets a bad rap for performance, but used correctly—with split providers and memoization—it's perfect for truly global state like themes, auth, and feature flags.

The Meta-Pattern

The real pattern is knowing which pattern to use. Start simple. Add complexity only when the code demands it. The best pattern is the one that makes your specific problem disappear.

Continuous Learning

React patterns evolve. Hooks replaced class lifecycle methods. Server Components are changing how we think about data fetching. Stay curious, keep learning, and always question if there's a better way.

Prabhath Madhushan

Prabhath Madhushan

Full Stack Developer | Software Engineer

A passionate developer building scalable web applications with modern technologies. Always learning, always creating.