← Back to React Course | Chapter 3: Components & Props | Lesson 7 of 11

Component Composition

Component composition means building a big UI out of smaller components, the same way a house is built from separately-made walls, doors, and windows.

Composing Components Together

A component can render other components inside its own JSX, the same way it would render a <div> or <p>. This lets you build a page by assembling smaller, well-defined pieces -- a Header, a Sidebar, a Footer -- into one larger App component.

Note: Name each small component after the specific UI piece it represents, like Header or UserCard, to keep composition easy to follow.

Warning: Nesting too many unrelated concerns into a single composed component defeats the purpose of splitting it up in the first place.

Example: Composing Components Together

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Header() {
      return <header><h1>My Site</h1></header>;
    }
    function Footer() {
      return <footer><p>&copy; 2024</p></footer>;
    }
    function App() {
      return (
        <div>
          <Header />
          <p>Main content goes here.</p>
          <Footer />
        </div>
      );
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Composition Over Inheritance

React strongly favors composition (combining components) over inheritance (extending a base class) for reusing code between components. Instead of creating a subclass of a component, you pass props and children to configure a shared component's behavior.

Note: If you find yourself wanting a component to inherit from another, look for a way to compose them together with props instead.

Warning: Coming from object-oriented languages, it's tempting to reach for class inheritance in React -- this is generally discouraged in favor of composition.

Example: Composition Over Inheritance

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Dialog({ title, children }) {
      return (
        <div style={{border: "1px solid #333", padding: "10px"}}>
          <h3>{title}</h3>
          {children}
        </div>
      );
    }
    function App() {
      return <Dialog title="Welcome"><p>This dialog is composed, not inherited.</p></Dialog>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Composing Multiple Levels Deep

Composition isn't limited to one level -- a composed component can itself be composed of other composed components, forming a tree. This mirrors how real applications are structured: a Page contains Sections, which contain Cards, which contain smaller pieces still.

Note: Deeply nested composition is normal and healthy in React -- don't worry about how many layers deep your component tree goes.

Warning: Losing track of where data originates in a deeply composed tree can make debugging harder -- keep prop names consistent as they pass down.

Example: Composing Multiple Levels Deep

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Icon({ symbol }) { return <span>{symbol}</span>; }
    function IconButton({ symbol, label }) {
      return <button><Icon symbol={symbol} /> {label}</button>;
    }
    function Toolbar() {
      return <div><IconButton symbol="+" label="Add" /><IconButton symbol="-" label="Remove" /></div>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Toolbar />);
  </script>
</body>
</html>
Common Mistakes
  1. Trying to cram everything into one giant component instead of splitting it into smaller, composed pieces.
  2. Duplicating markup across components instead of extracting a shared, composed piece.
  3. Over-composing trivially simple UI into too many tiny components, adding unnecessary complexity.
Chapter Summary
  • Composition means building complex UI by combining simpler components together.
  • Components can be nested inside each other just like HTML elements.
  • Composition favors combining small, focused components over one large component.
  • It's the primary way React encourages code reuse, as opposed to inheritance.
Browser Support

No browser-specific restrictions -- composition is a core React design pattern.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.