Search tldr

Modularizing React Applications with Established UI Patterns

React should serve as the view layer—not the home for networking, state orchestration, data transformation, and business rules. Applying presentation-domain-data layering makes frontend code easier to test, evolve, reuse, and potentially migrate to another UI technology.

Share

Modularizing React Applications with Established UI Patterns

Author: Juntao QIU | 邱俊涛 | Published: 2023-02-16 | Generated: 2025-02-13 | Domain: martinfowler.com
Tags: ‘#react’ ‘#frontend-architecture’ ‘#layered-architecture’ ‘#refactoring’ ‘#design-patterns’


TLDR

React is a UI library, so components and hooks should not become catch-all containers for rendering, data fetching, state management, API transformation, and domain logic. The article demonstrates progressively refactoring a payment feature into thin presentational components, stateful hooks, domain models and strategies, and a network gateway. This presentation-domain-data layering reduces cognitive load and shotgun surgery while making business logic independently testable and reusable beyond React.

Key Takeaways

  • Separate view from non-view logic: Keep components focused on rendering and user interaction; move state coordination into hooks and isolate domain calculations, transformations, and external-system access elsewhere.
  • Evolve deliberately as complexity grows: A single component can be split into focused components, reusable hooks, domain objects, and ultimately presentation, domain, and data layers rather than retaining an “everything in component” structure.
  • Encapsulate business rules in domain models: The PaymentMethod model owns labels and default-selection behavior, preventing UI-specific conditionals such as checking whether the provider is "cash" from leaking across views.
  • Use polymorphism to prevent shotgun surgery: Country-specific donation rounding and currency formatting are captured in a PaymentStrategy/CountryPayment abstraction, replacing scattered country-code branches in hooks, components, and formatting functions.
  • Create an API boundary: Extracting payment-method retrieval and conversion into a gateway/anti-corruption layer localizes remote API changes and lets React-focused libraries such as React Query manage network concerns.

Images & Media

  • React Homepage — React’s definition of itself as a JavaScript library for building user interfaces.
  • Presentation Domain Data Layering — Martin Fowler’s description of view, domain, and data-layer modularization.
  • Extract Function — Refactoring technique used to extract hooks, helpers, and components.
  • Replace Conditional with Polymorphism — Refactoring used to replace country-code branching with payment strategies.
  • React Query — Suggested library for handling network fetching, retries, caching, and related concerns.
  • Gateway — Pattern for encapsulating access to an external service or resource.

Keep reading