Composition vs Inheritance in React.JS
Intro to composition vs inheritance
Welcome to the composition vs inheritance in React comparison.
If you’re a senior developer or architect, I bet you know the most popular concepts, design patterns, and how stuff works inside. But still, not many front-end devs go think so much about composition and inheritance.
It’s not an often discussed topic, and I’ve noticed not all devs can explain why they created their solution with this or this way.
In today’s article, we’ll talk about two programming concepts, composition and inheritance.
I will tell you what composition is and what inheritance is, but not only.
You’ll learn about how they look in js as well in React.js.
Next, we’ll compare them together and look at which one is better to use, when to use composition and when it is better to go with inheritance.
Because it’s an article related to composition vs inheritance targeted to React, I will not go very deep in programming concepts as inheritance or composition in general. I will just explain them shortly, and I’ll focus on the topic - the comparison.
Let’s start!
And if you prefer video, here is the youtube version with whiteboarding:
Inheritance in JavaScript
Inheritance in JavaScript is an OOP programming concept that lets us inherit a parent’s features from the child.
For example, if we can create a parent like a vehicle with a property like every vehicle has, let’s say, wheels, gearbox, engine, and lights.
Next, we can create a car as a child of vehicle, that inherits properties of vehicle.
It means our car is a vehicle, so it will have wheels, lights, engine, and gearbox from scratch.
Of course, we can add more features to our object.
Let’s see the code example:
function vehicle() {
this.engine = true;
this.lights = 4;
this.gearbox = true;
this.wheels = 4;
}
function car(color, power) {
vehicle.call(this);
this.color = color;
this.power = power;
}
const newCar = new car('red', 1000);
console.log(newCar);
// {
// color: "red",
// engine: true,
// gearbox: true,
// lights: 4,
// power: 1000,
// wheels: 4
// }
What is composition in JavaScript
There is class-related composition (that is a bit more complicated but gives us props of still using inheritance) and function composition.
We will not go so deep into the general composition concept, but I’ll try to explain the concept as much as possible until we go into the React case.
This is the simple function composition.
So we do have two features, starting lights and starting engine.
Mechanical vehicles can start lights and start an engine together composed into the mechanicalFeatures by Object.assign.
Next, we can create a car with its own carFeatures features like opening windows, but it still has all the mechanical features.
To achieve that, we needed to compose carFeatures with mechanicalFeatures, and we return it in the car’s object constructor.
The result is, the car has all of these features and can call off the methods.
Let’s see the code example:
const canStartLights = self => ({
startLights: () => console.log(`Starting all ${self.lights} lights`)
});
const canStartEngine = self => ({
startEngine: () => console.log(`Starting engine, and ${self.power}HP makes noise`)
});
const mechanicalFeatures = self => Object.assign({}, canStartLights(self), canStartEngine(self));
const car = (lights, power, windows, color) => {
const self = {
lights, power, windows, color
}
const carFeatures = self => ({
openWindows: () => console.log(`${self.color} car is opening all ${self.windows} windows`)
})
return Object.assign(self, mechanicalFeatures(self), carFeatures(self));
}
const newCar = car(4, 700, 2, 'Red');
newCar.startEngine();
// Starting engine, and 700HP makes noise
newCar.startLights();
// Starting all 4 lights
newCar.openWindows();
// Red car is opening all 2 windows
Inheritance in React
Inheritance in React is very similar to the JS one, and there is not so much to add about that topic.
For example, if we go with the class, there is as same inheritance as with the JavaScript classes.
We can use just a simple extend to inherit methods from the parents component.
Let’s take a look on the code example:
class Vehicle {
constructor(color) {
this.color = color;
}
}
class Car extends vehicle {}
const redCar = new Car(„red");
With functional inheritance, you could do it by creating a new instance, but it’s not a so popular solution used in React, and in the next steps, I’ll explain to you why you shouldn’t even bother so much with that topic.
What is a component composition in React
The component composition is one of the most essential patterns in React related to the components model.
It helps us to build even very complex functions by using many small parts.
By using composition, we can implement other components into the component.
For example, when we build the user profile, we can create the userProfile component, put components userPhoto, and use userDescription as child props.
Let’s see the code example:
const UserProfile = props => {
return <div className="user-profile">{props.children}</div>
}
<UserProfile>
<UserPhoto/>
<UserDescription/>
</UserProfile>
What’s going on with composition vs Inheritance in React
The composition wasn’t trendy in JavaScript (and definitely not before es6), and the most often used always was OOP style classic inheritance, but everything changed when React came in the game.
React’s design and architecture use composition in a fantastic way that shortens development time a lot, but not only. There are a few benefits strictly to React that I’ll tell about a bit later.
All of that resulted in a bit confusing programming approach, and not everybody knew which concept is the right one when we build apps in React.js.
Reason for composition over inheritance
When we develop apps to React, there are a few main reasons why we should go with composition over inheritance.
The first one is the possibility of avoiding too nested components.
Because of props.children, we can separate code in the separated places. We do not need to go very deep in the components and create many ifs.
The next important thing. With composition, we follow the “everything is component” model designed by React.
It’s safer to use composition because we do not interact.
We can still use them with a bit of inheritance, for example, when we build composed high-order components (HOC), but about HOC, I’ll create a separate article because it’s a large topic.
Why not composition over inheritance
If we talk about React.JS, there is probably no reason to go with classic inheritance instead of composition.
Even if we go into the React.JS documentation, the authors said they have found no cases to go oppositely.
It’s React’s point of view, and here it’s true. Their composition concept is fantastic and works well.
With other cases like pure JavaScript, I’d say classic inheritance can be much handier, and it’s much easier to use for non-experienced developers.
In some cases (not in React), the handiest can be for us, the class composition with superclasses, subclasses, and extending.
So it’s a bit like a mix of benefits from classic inheritance and composition, but it’s definitely not a very beginner-friendly pattern.
Summary of composition vs inheritance
Now you’ve learned how composition and inheritance works, congratulations!
You know differences and when to use each of them, as well.
I’m sure now, you will not only know which one is better for your situation, but you’ll understand what is in the ongoing project, if it’s correct, and why it’s worth to refactor.
It was the next episode of our React series when we go into React a bit deeper than just creating UI or API calls.
My idea is to show you how React.JS really works, why things happen, how it works inside, and give you enough knowledge to design and manage enterprise-level solutions built with React.js.
Thanks for reading, and see you in the next one episodes of React in-depth,
Radek from Duomly