React 101 - Composition vs Inheritance

React recommends using composition instead of inheritance. But what is composition? What is inheritance? Why should we use one over the other?

It's hard to understand without a concrete example, so let's just say we are building two very simple payment method forms. We need one form to create a new payment method, and another form to update an existing payment method.

So what we can create a PaymentMethodForm class with just one input:

See the Pen react-payment-form by Brew Creative Limited (@brew) on CodePen.

Very simple! So this simple form would be the basis for our create and update form. What's missing are the buttons 'create' and 'update'. And since they share the same form element, we can use the PaymentMethodForm class as the parent class and extend from it.

Inheritance

See the Pen react-payment-form-inherit by Brew Creative Limited (@brew) on CodePen.

Above, we created two new classes - CreatePaymentMethodForm and UpdatePaymentMethodForm, which extends the PaymentMethodForm class. In the render method, it uses super.render() to fetch the output from the parent class, and adds a button underneath it.

This is creating a new component using inheritance because we are inheriting methods (super.render()) from the parent class, and using it in the child class.

Composition

But this is not the only way to achieve the same result. Instead of extending the PaymentMethodForm class, we can, instead, create an instance of the PaymentMethodForm component, and using the component inside our component.

See the Pen react-payment-form-composite by Brew Creative Limited (@brew) on CodePen.

Above, the CreatePaymentMethodForm and CreatePaymentMethodForm class both extends from React.Component, and uses an instance of PaymentMethodForm - <PaymentMethodForm /> - inside its render method.

Here, we can creating new components by putting one or more components together.

Which is better?

The React team is not saying composition is better than inheritance, it is saying it is better when applied to React components. Imagine your user interface as a table - it is made up of one top and several legs. The legs and the top are components which make up the table. Because React is also components-based, using composition might be more fitting when writing a React application.

However, there is nothing stopping you from using inheritance. If you're creating several 'button' components, you might want to create a more generic Button class and have several other button classes extending from that.

The problem with inheritance is more to do with people misusing it. Generally:

  • A Tesla Model 3 is a type of car, so you can make TeslaModel3 a proper subclass of Car. Everything that a generic car can do, a Tesla Model 3 can do. So this is using inheritance properly.
  • On the other hand, a Toyota HiAce may share similarities to a car, but it might only have 2 seats instead of five, its doors open differently etc. So it should not extend from the Car class. Instead, we can either:

    • Abstract the Car class even further into a Vehicle class, and extend a Van class from the Vehicle class, or
    • Break the Car class into smaller components (like Wheels, Doors etc, and combine them in a different fashion to form the van.

    If you find the subclasses are overriding the parent class' methods, then maybe think about choosing a different parent class (first example), or using composition instead of inheritance (second example).

A final consideration - when there is an established and officially-supported style, it is often more practical heed the advice. So for that reason, when using React, we recommend preferring composition vs inheritance, and only using inheritance when the using composition would be impractical.

See this excellent article by Steven Lowe on how (and when) to use composition and inheritance together.

Daniel Li

Full-stack Web Developer in Hong Kong. Founder of Brew.

Hong Kong http://danyll.com