Open In App

React JS Component Composition

Last Updated : 05 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • Code Reusability: Composition allows you to create small, focused, and reusable components or modules. By reusing existing code in various parts of your application, you reduce redundancy and maintain a more efficient codebase.
  • Modularity: Composing applications from smaller, independent modules makes it easier to understand, test, and maintain code. This modularity can result in faster development cycles and quicker debugging processes.
  • Optimized Code Loading: In scenarios like lazy loading or dynamic imports, composition allows loading only the components needed for a particular feature. This can significantly reduce initial page load times, improving the overall performance of your application.
  • Parallel Development: When different teams or developers work on independent components, they can progress simultaneously without interfering with each other’s work. This parallel development approach speeds up the overall development lifecycle.

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.

Javascript




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


Javascript




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


Javascript




// 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 :

article-output1
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.

Javascript




// 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;


Javascript




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


Output :

article-exm2Higher 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.

Javascript




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


Javascript




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


Output :

Hoc-article

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.

Javascript




// 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;


Javascript




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


Output :

render-prop

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

Javascript




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 :

article-child

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.

Javascript




// 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;


Javascript




// 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;


Javascript




// 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 :

Screenshot-2024-03-03-133738

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.

Javascript




// 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 :

Screenshot-2024-03-02-231534

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.

Javascript




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 :

article-child

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.

Javascript




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:

Screenshot-2024-03-02-202642

Why Composition Wins Over Inheritance?

Composition wins over inheritance for several reasons:

  • Flexibility : Composition allows components to be more flexible than inheritance. Using Composition we can dynamically compose components at run time but whereas with inheritance it maintains a static relationship between components which is defined at compile time. Compositon ensures code reusability across various situations.
  • Simplicity : Composition encourages components to be more simpler and focused. Each component is assigned a specific responsibility making the component independent and also the code easier to understand and maintain.
  • Reusability : Composition helps us create more simpler and reusable components that are combined to create more complex React applications. Composition also avoids code duplication, and reduces the code’s size to make it more modular and maintable.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads