Component Composition vs Inheritance in React

React reuses components through composition, not inheritance. Learn how props and children replace class hierarchies in React.

5 min read

React recommends composition over inheritance for reusing code between components. Instead of extending a base class, you pass props and nest JSX. Because components are functions, composition maps directly onto them.

The difference at a glance

CompositionInheritance
How you reusePass props and nest JSXExtend a base class
React supportFirst classNot used for components
FlexibilityHigh, any value or JSXRigid class hierarchy

Composition wins in React because a component is just a function that returns UI. There is no class to extend, and props can carry any value, including JSX. This is not a stylistic debate, because function components have no extends keyword at all.

Containment with children

When a component wraps other content, it receives that content as the children prop. This is how a Dialog stays generic:

App.jsxApp.jsx
function Dialog({ title, children }) {
  return (
    <div className="dialog">
      <h2>{title}</h2>
      {children}
    </div>
  );
}

Any parent can fill the dialog with different content. The Dialog supplies the frame, and the parent supplies the body. The children prop guide shows more real examples.

You can also pass several named JSX props when a wrapper has more than one area.

Specialization with props

For a more specific version of a component, render the generic one with fixed props:

App.jsxApp.jsx
function WelcomeDialog() {
  return <Dialog title="Welcome">Thanks for joining.</Dialog>;
}

WelcomeDialog is a specialized Dialog, built by composition rather than by extending a Dialog class. This pattern is clearer than a hierarchy because every relationship is visible where it is used.

Share logic without inheritance

Inheritance was also used to share behavior, like a logging mixin. In React, that job belongs to plain functions and custom hooks.

App.jsxApp.jsx
function formatPrice(amount) {
  return "$" + amount.toFixed(2);
}

Any component can import and call this function. For stateful logic, a custom hook provides the same sharing without a class hierarchy. Composition keeps behavior in small, composable pieces instead of a chain of base classes.

Why inheritance is not needed

The cases inheritance used to solve all have a composition equivalent.

  • Reuse UI: pass props or nest children.
  • Add behavior: wrap with a component or use a custom hook.
  • Share logic: extract a function or a hook.

Function components make inheritance unnecessary, and the result is code that is easier to read because each piece is a small function rather than a deep class hierarchy. The passing props guide covers the mechanics of the props side of composition.

What to learn next

Practice containment with the children prop, then see how to reuse one component in many places with different props and children.

Rune AI

Rune AI

Key Insights

  • React recommends composition over inheritance.
  • Components are functions, not classes you extend.
  • Containment wraps content with the children prop.
  • Specialization renders a generic component with fixed props.
  • Props and children cover the reuse cases inheritance used to solve.
RunePowered by Rune AI

Frequently Asked Questions

Does React use inheritance between components?

No. React components are functions, and you reuse them by passing props and nesting JSX. Inheritance is not used to build component hierarchies.

How do I reuse a component in React?

Compose it. Pass different props to specialize it, and nest JSX as children when it wraps content. There is no need to extend a base component.

What replaced mixins and inheritance in React?

Function components with props and the children prop. Patterns like higher-order components and custom hooks also emerged to share logic without class hierarchies.

Conclusion

React is built around composition, not inheritance. Reuse a component by passing props to specialize it and nesting JSX as children when it wraps content. This keeps components small, explicit, and easy to change.