Component Architecture

Medium•

Structuring components for maintainability, reusability, and scalability.

Quick Navigation: Patterns • Organization • Composition • Design Systems

Component Patterns

Presentational vs Container

Presentational (Dumb)

  • • Only renders UI based on props
  • • No business logic or state
  • • Highly reusable

Container (Smart)

  • • Manages state and side effects
  • • Fetches data
  • • Passes data to presentational

💡 Note: With hooks, this pattern is less common. Use it when separation benefits testing or reuse.

Compound Components

Components that work together implicitly sharing state.

Pros

  • ✓ Flexible composition
  • ✓ Clean API (no prop drilling)
  • ✓ Great for UI libraries

Cons

  • ✗ More complex implementation
  • ✗ Harder to type with TypeScript

Render Props vs Hooks

Render Props

  • • Pass function as child
  • • Works in class components
  • • Can cause "callback hell"

Custom Hooks

  • • Modern React approach
  • • Cleaner, more readable
  • • Composable

✅ Recommendation: Prefer hooks for new code, render props for backward compatibility.

File Organization

By Type

src/
├── components/
├── hooks/
├── utils/
├── services/
├── pages/
└── styles/
✓ Simple, familiar structure
✗ Related files scattered

By Feature

src/
├── features/
│   ├── auth/
│   ├── dashboard/
│   └── products/
├── shared/
│   ├── components/
│   └── hooks/
└── app/
✓ Colocated, easier to navigate
✗ Can lead to duplication

Component Folder Structure

Button/
├── Button.tsx          # Main component
├── Button.test.tsx     # Tests
├── Button.stories.tsx  # Storybook
├── Button.module.css   # Styles (if CSS Modules)
├── useButton.ts        # Hook (if complex logic)
└── index.ts            # Re-exports

Composition vs Inheritance

Composition (Preferred)

Build complex components from simpler ones.

✓ Flexible and reusable
✓ Easier to test
✓ React's recommended approach
✓ Avoids prop drilling with children

Inheritance (Avoid)

Extend base component classes.

✗ Tight coupling
✗ Hard to modify base class
✗ Not how React works

Composition Patterns

  • Children: <Card><Content /></Card>
  • Slots: <Layout header={<Header />} sidebar={<Sidebar />} />
  • HOCs: withAuth(Component)
  • Render Props: <Mouse render={mouse => <Cat mouse={mouse} />} />

Design Systems

Build Your Own

  • ✓Full control and customization
  • ✓Matches brand perfectly
  • ✗Significant time investment
  • ✗Accessibility burden on you

Use Existing (Radix, shadcn/ui)

  • ✓Accessibility built-in
  • ✓Faster development
  • ✓Community tested
  • ✗May need customization

Best Practices

  • 1.Single responsibility. Each component does one thing well.
  • 2.Composition over inheritance. Build complex from simple.
  • 3.Colocate related files. Keep component, tests, styles together.
  • 4.Props interface first. Design the API before implementation.
  • 5.Extract custom hooks. Share logic between components.