Difference between Composition and Inheritance in React

Sneha Mallik
Last Updated: May 13, 2022

Introduction 

When it comes to code reusability, composition and inheritance are two crucial aspects of object-oriented programming. Both of these apply to React components as well. As a result, the distinction between inheritance and composition is crucial.

 

Are you confused about whether to learn React? Check out the blog Learning React JS for Front-End Web Development.

 

This blog will cover the concept of composition and inheritance in React, the difference between composition and inheritance in React.

Composition

In Object-Oriented Programmingcomposition is a well-known concept. It describes a class that can refer to one or more objects of another class as instances rather than inheriting properties from a base class.

 

For example, the composition can be used for building a car's engine.

 

What is the definition of composition in general? 
 

It's all about the ingredients and how they're put together to become something more significant. A dish is made up of food ingredients while cooking. The fruits are used to make the ideal smoothie. In a dance video, it's the choreography of dancers. In programming, the internals of a function must be organized so that the intended output is obtained.

Inheritance

Inheritance is an Object-Oriented Programming concept in JavaScript that allows us to inherit the features of a parent from the child.
 

For example, suppose we can design a parent that looks like a vehicle and has properties like wheels, engine, gearbox and lights.

 

Then, as a vehicle child, we may make a car that inherits the vehicle's(Parent) properties.

 

It means that the car(Child) is a vehicle that will have wheels, lights, an engine, and a gearbox from the start. 
 

We can also extend the functionality of our object(here, car) by adding more features.

Composition VS Inheritance

The techniques for using several components together are done by composition and inheritance in React. This facilitates code reuse. React recommends using composition instead of inheritance as far as feasible, and inheritance should only be utilized in particular instances.

 

The ‘is-a relationship’ mechanism was used in inheritance. Derived components had to inherit the properties of the base component, which made changing the behaviour of any component quite difficult. The composition aspires to be better. Why not inherit only behaviour and add it to the desired component instead of inheriting properties from other components?

 

Only the behaviour is passed down from composition without the inheritance of properties. Why is this a plus point? It was challenging to add new behaviour via inheritance as the derived component inherited all of the parent class's properties, making it impossible to add new behaviour. More use cases had to be included. However, we only inherit behaviour in composition, and adding new behaviour is relatively easy.

 

React proposes utilizing composition instead of inheritance to reuse code between components because React has an advanced composition model. Between Composition and Inheritance in React, we can distinguish the following points:

  • We can overuse ‘inheritance’.
  • ‘Behavior’ composition can be made simpler and easier.
  • Composition is preferred over deep inheritance in React.
  • Inheritance inherits the properties of other components, whereas composition merely inherits the behaviour of other components.
  • It was difficult to add new behaviour via inheritance since the derived component inherits all of the parent class's properties, making it impossible to add new behaviour.

Composition: Using Props.children

Some parent components aren't aware of their children in advance. This is especially typical for components that represent generic ‘boxes’, such as ‘Sidebar’ or ‘DialogBox’.

 

Such components transmit the children elements directly into their output using the special children prop. By nesting the JSX(Javascript XML), other components can send arbitrary children to them.

 

Anything inside the JSX tag <CustomisedBorder> gets supplied as a children prop to the CustomisedBorder component. The provided items appear in the final result because CustomisedBorder renders the {props.children} inside a <div>.
 

function CustomisedBorder(props){
    return(
        <div className = {'CustomisedBorder CustomisedBorder-' + 
        props.color}>
            {props.children}
        </div>
    );
}

function DialogWelcome(){
    return(
        <CustomisedBorder color = "red">
            <h1 className = "title">
                Welcome to CodeStudio!
            </h1>
            <p className = "message">
                Thank you for visiting! Have a good day!
            </p>
        </CustomisedBorder>       
    );
}

 

From this, we can draw the conclusion that-

  • Within <CustomisedBorder>, all components become {props.children}.
  • For layout/style, the parent component can wrap the children in a <div> tag.

Composition: Child Groups

Although uncommon, multiple "holes" in a component may be required on occasion. Instead of using children, we can create our own convention.

 

<Problems /> and <Code Editor /> are some React elements that can be passed as props just like any other data. This method reminds us of the ‘slots’ in other frameworks/libraries, but what we may send as props in React is unrestricted, and there are no limitations.


function DSAPractice(props){
    return(
        <div className = "DSAPractice">
            <div className = "DSAPracticeLeft">
                {props.left}
            </div>
            <div className = "DSAPracticeRight">
                {props.right}
            </div>
        </div>
    );
}

function Application(){
    return(
        <DSAPractice 
        left={<Problems />}
        right={<Code Editor />} />
    );
}

 

From this, we can draw the conclusion that-

  • Children can appear in several locations in some components.
  • Assign the child components to the prop names as it will help us in organizing.

Composition: Classes


Components are sometimes thought of as "special cases" of other components. A WelcomeDialog, for example, could be considered a subset of Dialog.

 

In React, this is also accomplished through composition, in which a more "particular" component renders and configures a more "generic" one with props.

function Dialog(props){
    return(
        <CustomisedBorder color = "red">
            <h1 className = "DialogTitle">
                {props.title}
            </h1>
            <p className = "DialogMessage">
                {props.message}
            </p>
            {props.children}
        </CustomisedBorder>
    );
}

class DialogSignUp extends react.Component{
    construct(props){
        super(props);
        this.handleChange=this.handleChange.bind(this);
        this.handleSignUp=this.handleSignUp.bind(this);
        this.state={course: ''};
    }

    handleChange(e){
        this.setState({course: e.target.value});
    }

    handleSignUp(){
        alert('Welcome to the ${this.state.course}! course');
    }

    render(){
        return(
            <Dialog title = "Higher Studies Program"
                    message = "Which course are you interested in?">
                <input value={this.state.course}
                      onChange={this.handleChange}/>
                <button onClick={this.handleSignUp}>
                    Sign Here!
                </button>
            </Dialog>
        );
    }
}

 

The composition also works for components that are declared as classes.

 

From this, we can draw the conclusion that-

  • Stateless Functions and Classes are both used together.
  • Specific Components can configure general Components.
  • Props can be used for configuration.

Implementing Inheritance

The keyword extends is used in inheritance. It allows the current component to use the methods and properties of an already existing component. Let’s see how to implement inheritance in React.

 

ParentClass:

import React from "react";

class ParentFunction extends React.Component{
    constructor(props){
        super(props);
        this.course = this.course.bind(this);
    }

    // Parent class function
    course(){
        console.log("This is the course you chose!");
    }

    render(){
        return false;
    }
}

 

The newly created Parent component itself uses the inheritance as the ParentClass extends the component from React as React.Component.

 

ChildComponent:

export default class ChildFunction extends ParentFunc{
    constructor(){
        super();
    }

    render(){

        // Parent component's properties are accessed by child component
        this.course();
        return false;
    }
}

 

Here the ChildFunction component extends the ParentFunction component. Here in the child class, the this.course() function is called from the parent class implementation.

Why not Component Inheritance?

Component inheritance hierarchies may be useful in creating reusable non-UI components, but a functional component is better off being isolated into its own JavaScript module.

Why Composition over Inheritance?

There are a few primary reasons why we should use composition over inheritance when developing React apps.

 

  • The first is the option of avoiding excessively nested components.
  • We can segregate code in different places, thanks to {props.children}. We don't need to go too deeply into the components and create a lot of ‘ifs’.
  • The next point is crucial. When it comes to composition, we use React's ‘everything is component’ concept.
  • Because we don't interact, it's safer to use composition in React.
  • We can still utilize them with a little inheritance, like when building composed high-order components (HOC).

Approach to Composition- HOC(Higher Order Components)

A function which takes a component and returns another component is known as a Higher Order Component (HOC). Inserting new props or context is one use case. This is a more complex technique that React uses.

 

Composition and inheritance in React both aim for code reuse and a more organized code structure. 

 

What does the React team, on the other hand, suggest?

React team suggests using Composition over Inheritance. React treats everything as a component and follows a strong component-based model. This is one of the main reasons why composition is a superior technique for code reuse than inheritance.

Frequently Asked Questions

1. What is the react composition model?

  • React Composition is a development approach based on React's original component model, in which we use explicitly defined props, or the implicit children prop to create components from other components.
     
  • In terms of refactoring, React composition is a pattern for breaking down a complicated component into smaller components and then composing those smaller components to structure and complete the application.
     
  • This strategy avoids creating too many comparable components with duplicate code, creating fewer components that can be reused throughout our application, making them easier to understand and maintain for your team.

 

  • React proposes utilizing composition rather than inheritance to reuse code between components because React has a powerful composition model.

 

2. What is component inheritance in react?

Component inheritance lets the react app make a parent-child component connection and reuse properties like state values and function in its child components.

Except for the initial component class, which extends from the react package, react does not employ inheritance.
 

The keyword ‘extends’ is used in inheritance to allow any component connected to the parent to use the attributes and methods of another component.

We can give the current component access to all of the component's properties, including the function, and activate it from the child component by using the ‘extends’ keyword.
 

3. What are the lifecycle methods in React components?

  • componentDidMount() : After the first render, componentDidMount() is called on the client side.
  • componentWillMount() : Calls componentWillMount() on both the client and server side before rendering.
  • componentWillUnmount() : Just before the component is destroyed, this function is invoked. This method should be used to perform any cleanup statements.
  • shouldComponentUpdate() : Based on specified criteria, this method returns a true or false value. Return true if you want your component to update or false if you don't want it to. It's set to false by default.
  • componentDidUpdate() : It is called as soon as the rendering is finished.
  • componentWillUpdate() : This method is called right before the DOM renders.
  • componentWillReceiveProps() : Called as soon as the parent class sends the props and before another render is called. 

Key Takeaways

In this blog, we went over the fundamentals of composition and inheritance in React. We also learned why composition is needed over inheritance and the difference between composition and inheritance in React.
 

Enroll in our Advance Front-end Web Development Course- React.js to deeply understand the concept of composition and inheritance in React. To prepare for a React interview, look through the React Interview Questions.

 

Credits: GIPHY

 

Happy Developing!

Was this article helpful ?
0 upvotes