Open In App

React JS Component Composition

Component composition in React involves the inclusion of one or more components in a single component, where each sub-component can further consist of additional components. Components in React are building blocks that are used to create user interfaces (UIs).

What is a Component Composition in React?

Component composition in React involves combining smaller, independent components to create complex UIs. Each sub-component can contain further components, enhancing code readability. This process breaks down the UI into manageable pieces, aiding traceability, scalability, and maintenance. Component composition facilitates easier debugging and isolated changes, making web development more efficient and maintainable.



How can composition help performance?

Composition can enhance performance in software development through several key mechanisms:

Steps to Create the React Application :

Step 1: Create a new react application using the following command.

npx create-react-app@latest my-app

Step 2: Navigate to the root directory of your folder app using the following command.

cd my-app

Example: This example demonstrates the use of composing components in React.




// App.js
  
import Welcome from './Welcome';
import Gfg from './Gfg';
function App() {
    return (
        <div >
            <Welcome />
            <Gfg />
        </div>
    );
}
  
export default App;




// Welcome.js
  
import React from 'react'
  
function Welcome() {
    return (
        <h1>Welcome to GeeksforGeeks</h1>
    )
}
  
export default Welcome




// Gfg.js
  
import React from 'react'
  
function Gfg() {
    return (
        <h1>Hello Coders!!!</h1>
    )
}
  
export default Gfg

Start your application using the following command.

npm start

Output :


Composing Components with props:

Composing components with props involves passing props through attributes to the components, and these components are composed in another component. Passing props through attributes to a component is similar to passing arguments to a JavaScript function. Props are like data packets that are passed down to child components from parent component, which helps child components customize their information and appearnce accordingly.

Example : This example demonstrates the use of composing components with props.




// App.js
import React, { } from 'react'
  
function App() {
    const Box1 = {
        backgroundColor: "blue",
        color: "white",
        padding: "10px 20px",
        width: "20px",
        height: "50px",
    };
  
    const Box2 = {
        backgroundColor: "red",
        color: "white",
        padding: "12px 25px",
        width: "30px",
        height: "50px",
    };
    return (
        <div >
            <Box text="Box1" style={Box1} />
            <Box text="Box2" style={Box2} />
        </div>
    );
}
  
export default App;




// Box.js
  
import React from 'react'
  
function Box(props) {
    return (
        <div style={props.style}>
            {props.text}
        </div>
    )
}
  
export default Box

Output :

Higher order components:

In React, a Higher Order Component (HOC) is a function that takes a component and returns a new one with added props or behavior. Similar to higher order functions in JavaScript, HOCs are used to reuse component logic throughout an application. They enable developers to enhance existing components with new props without altering the original component code, thus avoiding unnecessary rewriting.

Example : This example demonstrates the implementation of higher order components in React.




// App.js
  
import React from 'react';
import HigherOrder from './HigherOrder';
  
function App(props) {
    return <h1>{props.newprop}</h1>
}
  
export default HigherOrder(App)




// HigherOrder.js
  
function HigherOrder(OldComponent) {
    return function NewComponent(props) {
        return <OldComponent
            {...props} newprop="I'm the newly added prop" />;
    };
}
export default HigherOrder;

Output :

Render Props pattern:

The Render Prop pattern in React involves passing a function as a prop to a component, which returns a React element. Instead of implementing its own rendering logic, the component calls this function. This pattern enables sharing and reusing rendering logic across multiple components. It’s particularly useful when a component possesses data but lacks the JSX definition to render it. In such cases, a parent component passes a function with JSX structure as a prop to the child component, which utilizes this function to render JSX.

Example : This example demonstrates the implementation of Rendering props in React.




// App.js
  
import React from 'react';
import JsxReceiver from './JsxReceiver.js'
function App() {
    return (
        // JsxReceiver is a Wrapper Component
        <JsxReceiver render={data => (
            <h1>{data}</h1>
        )} />
    );
}
export default App;




import React from 'react'
  
function JsxReceiver({ render }) {
    let data = "Welcome to GeeksforGeeks";
    return render(data);
}
  
export default JsxReceiver

Output :

Using Hooks in Component Composition:

In React Hooks is a feature that helps us to use State and other React features in a functional Component without using a Class Component. If we look into the older versions of React, there were no Hooks and there is only used to be a Class Component through which we can use the “State” object , later in the React version 16.8 they introduced a new feature that is Hooks through which we can use ‘State‘ without even using a Class Component. The main pupose of Hooks is to allow functional components to have access to State and other features of react without the necessity of class component. In Component composition Hooks are used to share and reuse the logic across multiple components, which also helps in reducing code redundancy.

Example: Below is an example of using Hooks in Component Composititons




import React, { useState } from 'react';
  
// Define a Custom Hook
function CustomHook() {
    const [variable, setVar] = useState("I'm a child component");
    return { variable, setVar };
}
  
function MyComponent() {
    const { variable } = CustomHook();
    return <div>{variable}</div>;
}
  
function App() {
    return <MyComponent />;
}
  
export default App;

Output :

Context API and Composition:

The Context API in React allows sharing state and logic across components without manually passing props through each level of the component tree. It provides global access to data via a Context, enabling nested and child components to access required data easily. By composing components within a Context component created using createContext(), data can be accessed using useContext() without needing props. This approach simplifies component composition and is particularly useful for sharing common state and logic throughout a component tree hierarchy.

Example: This example demostrates the implementation of Context API.




// App.js
  
import React, { createContext } from "react";
import ParentComponent from "./ParentComponent";
  
export const NewContext = createContext();
  
const text = {
    parent: "I'm from parent Component",
    child: "I'm from child Component"
};
  
function App() {
    return (
        <NewContext.Provider value={text}>
            <ParentComponent />
        </NewContext.Provider>
    );
}
export default App;




// ParentComponent.js
  
import React, { useContext } from "react";
import { NewContext } from "./App";
import ChildComponent from "./ChildComponent";
  
function ParentComponent() {
    const data = useContext(NewContext);
    return (
        <div>
            <h1> {data.parent} </h1>
            <ChildComponent />
        </div>
    );
};
  
export default ParentComponent;




// Childcomponent.js
  
import React, { useContext } from "react";
import { NewContext } from "./App";
  
function ChildComponent() {
    const data = useContext(NewContext);
    return (
        <h1> {data.child} </h1>
    );
}
export default ChildComponent;

Output :

Compound Components:

Compound Components in React are patterns where the parent component shares its implicit State and logic with the child component using the Context API. Here the Child component depends on the state and logic provided by the parent component. Compound Component allows the child component to communicate with the parent component which leads to a more cleaner API’s. The child component doesn’t need to worry much about the data because it can directly get it from the parent component.

Example: Now, let us understand Compound Components through an example.




// App.js 
  
import React, {
    createContext,
    useState,
    useContext
} from 'react';
  
const NewComponent = createContext();
  
function ParentComponent({ children }) {
    const [variable, setVar] = useState("I'm a Parent Component");
  
    return (
        <NewComponent.Provider value={{ variable, setVar }}>
            {children}
        </NewComponent.Provider>
    );
}
  
function ChildComponent() {
    const { variable } = useContext(NewComponent);
  
    return <h1>{variable}</h1>;
}
  
function App() {
    return (
        <ParentComponent>
            <ChildComponent />
        </ParentComponent>
    );
}
  
export default App

Output :

Component Composition Patterns:

Containment Pattern:

In React, Containment Pattern is a “Parent-Child pattern” that manages the state and logic for a specific section of UI. It involves a parent component that encapsulates one or more child components. The parent component can also pass props to child components, these child components are responsible for presenting the UI based on the props it has received. Containment pattern allows parent component to pass the same logic or data across multiple components that utilzes this data to implement its own render logic or JSX.

Example: This example demonstrates the implementation of Containment Pattern.




import React from "react";
  
function ParentComponent({ children }) {
    return <h1>{children}</h1>;
}
function ChildComponent() {
    return <div> I'm a Child Component </div>;
}
  
function App() {
    return (
        <ParentComponent>
            <ChildComponent />
        </ParentComponent>
    );
}
  
export default App;

Output :

Specialization Pattern :

The specialization pattern is also known as “Inheritance pattern” that creates a new component by inheriting the props of a base component. The new component either adds some new functionalities or overrides the functinalities which are present in it and implements it own render logic.

Example : This example demonstrates implementation of specialized pattern.




import React from "react";
  
function ChildComponent({ data }) {
    return (
        <div>
            {data}
            <div>I'm a Child Component</div>
        </div>
    );
}
function ParentComponent() {
    const data = "I'm a parent component";
    return (
        <ChildComponent data={data} />
    );
}
function App() {
    return (
        <ParentComponent />
    );
}
export default App;

Output:

Why Composition Wins Over Inheritance?

Composition wins over inheritance for several reasons:


Article Tags :