Composition and Inheritance: A React Story

The first time I read through the legendary React Docs, I didn’t understand the importance of section 11 in Main Concepts: Composition vs Inheritance. After taking more time to study React, the difference between these two concepts and the reason why one might be preferred over another became more clear.

What are composition and inheritance?

Short answer: they are means of transmitting attributes that are shared by multiple objects. Here’s a classic Javascript inheritance example:

I’ve got something big and general. So what if I want something more specific, like a grocery store?

Our code is growing, but since we’ve already got Store giving us logic for things like name and location, we can ask our GroceryStore to inherit those attributes:

Nice! The super inside of constructor allows us to assign the name and city attributes in the exact same way our parent class, Store, would. Since Store doesn’t have a discountFruit attribute, we assign that manually. We can also use super to reference methods from the parent class.

Okay, so this seems to be working and is certainly useful. So why do Dan Abramov and the React Docs suggest always using composition over inheritance? After doing a bunch of research, I’ve come to the following conclusions:

  • Composition is more flexible and customizable
  • React was built with the intention of composition behind it, so it’s best to stick with that.

Here’s a display of a react component and composition at work:

In my app file, I call on a Bicycle component and assign it some properties. We can see that they are weight (an integer) and ring (a function). Here’s what the Bicycle component looks like:

This component will render a “Bicycle” to the page. The user viewing the page will be able to see the text that describes the bicycle and click a button that triggers a “ring” function. This is because React components allow us to compose objects, like I did in App.

This works the same way as inheritance, but it’s so customizable and straightforward. You can clearly see in App what attributes I’m assigning and what they’re called. No need for super() or .protoype or extra lines of code within your child class to re-declare a function that was passed down. Composition is also incredibly useful in that it can create higher-order functions and even higher-order components, leaving limitless possibilities for customization and efficiency maximization.

Solutions Engineer