Composition vs Inheritance in React | Comparison and Contrast
Download this gorgeous React Native Store Locator app template to create your own store finder app in just a few minutes. By using this fully-coded starter kit written in React Native, you’re saving weeks of design and development and can focus on other important efforts such as customer engagement and marketing.
If you have any knowledge regarding object-oriented programming, then you may have heard these two words — Inheritance and Composition. Inheritance and Composition are two important parts of object-oriented programming when it comes to code reusability. Both of these concepts are also relevant to React components. Hence, the concept of inheritance vs composition is very important.
Building components in React is fun but it can be tedious sometimes. Suppose, one component needs a button with blue color and the other needs a button with a black border. Similarly, a third component needs a button with a yellow color and blue border. Now, writing code for a button every time with just different styling is, of course, tedious and a bit frustrating. There should be ways of reusing the code and enhancing the components.
Yes, inheritance and composition both can be used for code reusability and for enhancing components but according to the core React team, we should prefer composition over inheritance.
As mentioned earlier, both inheritance and composition are parts of object-oriented programming. Both of these concepts are heavily used in programming for better code reusability and enhancement. In this article, we will discuss which works better in react, Inheritance or Composition.
Inheritance is a concept in object-oriented programming in which one class inherits properties and methods of another class. This is useful in code reusability. Let’s see it implemented in React.
Implementation
import React from 'react';
import './App.css';
class Vehicle extends React.Component{
constructor(props){
super(props)
this.className = 'Vehicle'
}
render(args){
return(
<h1 className={this.className}>{this.props.children}{args}</h1>
)
}
}
class Car extends Vehicle{
constructor(props){
super(props)
}
}
class Bike extends Vehicle{
constructor(props){
super(props)
}
}
class Main extends React.Component{
render(){
return(
<React.Fragment>
<Vehicle>Vehicle</Vehicle>
<Car>Car</Car>
<Bike>Bike</Bike>
</React.Fragment>
)
}
}
export default Main;
There are three components used in the main class, Vehicle, Car and Bike. The vehicle is the base class while Car and Bike class are derived from it using the extends keyword. The Car and bikes classes are inheriting properties of the Vehicle class. The render method in the Vehicle class is inherited by both the derived classes. Also, the className property is also inherited by the Car and Bike class.
Adding another component
Let’s add another component. This component will aim to print the name of the vehicle as we did earlier using this.props.children. But this time, it will also print an additional text with it that will be passed from this very component. The following class is also a derived class of the Vehicle class with additional working.
class Truck extends Vehicle {
constructor(props){
super(props)
}
render(){
return <div>
{super.render()}<span> is a heavy vehicle</span>
</div>
}
}
We used a render method in this component. Remember, there is an inheritance of render method of the Vehicle class by this class. So to add the additional text, we have to use the super method to call the render method of the base class. Let’s observe the output.
Now, this is not what we expected. “Truck is a heavy vehicle”, this should be in one line with a single CSS. This is one disadvantage of using inheritance in React. However, we can achieve the desired results by using arguments. Let see how to do it.
//Vehicle class
class Vehicle extends React.Component{
constructor(props){
super(props)
this.className = 'Vehicle'
}
render(args){
return(
<h1 className={this.className}>{this.props.children} {args}</h1>
)
}
}
//Truck class
class Truck extends Vehicle{
constructor(props){
super(props)
}
render(){
return <div>{super.render(<span> is a heavy vehicle</span>)}</div>
}
}
Observe the changes made in the Vehicle and Truck classes.
In the Truck class, we passed the span tag with text to the render method of the base class,i.e. Vehicle.
In the Vehicle class, we used the argument and print it with the vehicle name. Let’s see if we get the desired output or not.
Yes, we got the desired output. But is this right? No, it isn’t. We passed the argument from the Truck class, but what about other classes? We should not use this method because the Vehicle class has to accommodate the use cases of another class. Remember, more the use cases, more the arguments. This looks alright here but when there are multiple cases similar to this, the code will become complex and it will be very difficult to maintain it. We use inheritance for code reusability so that code looks less complicated in the first place? Don’t we?
There is a better way to code reusability and enhancing the components. Inheritance used the is-a relationship method. Derived components had to inherit the properties of the base component and it was quite complicated while modifying the behavior of any component. The composition aims for something better. Instead of inheriting the properties of other components, why not inherit only behavior, and add behavior to the desired component?
Composition does not inherit properties, only the behavior. This is a plus point but why? In inheritance, it was difficult to add new behavior because the derived component was inheriting all the properties of parent class and it was quite difficult to add new behavior. We had to add more uses cases. But in composition, we only inherit behavior and adding new behavior is fairly simple and easy. Let’s understand this with the help of an example that is the modified version of the earlier example.
Implementation
import React from 'react';
import './App.css';
class Vehicle extends React.Component{
render(){
return(<h1 className=”Vehicle”>{this.props.children}</h1>)
}
}
class Car extends React.Component{
render(){
return(<Vehicle>{this.props.children}</Vehicle>)
}
}
class Bike extends React.Component{
render(){
return(<Vehicle>{this.props.children}</Vehicle>)
}
}
class Main extends React.Component{
render(){
return(<React.Fragment>
<Vehicle>Vehicle</Vehicle>
<Car>Car</Car>
<Bike>Bike</Bike>
</React.Fragment>
)
}
}
export default Main;
In the above code, we used Composition. Observe carefully, None of the code is inheriting from any other component. But we can see, the Car and Bike classes are inheriting the behavior of the Vehicle class. We just used the Vehicle component inside both the classes. Let’s see the output.
Clearly, the Car and Bike classes are inheriting the behavior of the Vehicle class. Now, let’s add one more component that will inherit the behavior of the Vehicle class, but along with existing behavior, we will add new behavior too.
class Truck extends React.Component{
render(){
return(
<Vehicle>{this.props.children}<span> is a heavy vehicle. </span></Vehicle>
)
}
}
Again we added a Truck component but this time we used Composition. We also added a new behavior to it. Look how easy it is. We do not need to do anything with the Vehicle class. Thus, not affecting any other component.
<Vehicle>{this.props.children}<span> is a heavy vehicle. </span></Vehicle>
Compare this with the inheritance one. Surely, the composition is easy and simple. We can add behaviors of our choice to any component without causing any trouble.
This completes our understanding of inheritance vs composition in React.
This is why composition is preferred over the inheritance. Using composition is quite easy and simple while inheritance becomes much complicated with the addition of more code. Adding behavior is so simple in the composition that we just need to change the code in component only. In inheritance, there is a complication to add new behavior. The addition of more behavior leads to more use cases, that in turn leads to more arguments. The code becomes more complicated and unmaintainable. Hence, it is logical to prefer composition over inheritance in React. Thus, this article circulates the concept of inheritance vs composition which is essential for any programmer.