Compound Component Design pattern In React

Compound Component Design pattern In React


Hello everyone again

Today I will talk about another react design pattern, which could Compound Components.

The Compound Components pattern is a technique used in ReactJS to create a set of components that are designed to work together to achieve a specific functionality or behavior. It allows you to encapsulate related components within a parent component and control their interaction and state collectively.

Unlike typical React component structures, where each component is responsible for its own rendering and state management, the Compound Components pattern distributes responsibilities across multiple components. The parent component acts as a coordinator, providing the infrastructure for managing shared state and controlling the behavior of its child components.


when we use this patter, we got several benefits in application development:

1. Encapsulation and Composition because this pattern promotes encapsulation by grouping related components together within a single parent component. This encapsulation allows you to create a higher-level abstraction that represents a specific functionality or feature of your application.

2. Improved Reusability : By splitting the functionality across multiple components and providing a clear interface, the Compound Components pattern enhances reusability. Each individual component can be used independently, but when combined within the parent component, they form a powerful and reusable unit. This promotes code reuse and reduces duplication across your application.

3. Flexibility and Customization because this pattern allows for flexible and customizable usage. Each child component can expose a set of props that allow consumers to customize its behavior or appearance. Consumers can selectively enable or disable specific child components, override default settings, or provide their own components within the parent component's structure.

4. Centralized State Management

In a Compound Components structure, the parent component typically manages the shared state and behavior that affects its child components. This centralized state management simplifies coordination between components and avoids the need for complex prop drilling or context sharing. It ensures that all related components stay in sync and allows for easy modification of the shared state when necessary.


Example


import React, { useState } from 'react';


const Tabs = ({ children }) => {
  const [activeTab, setActiveTab] = useState(0);


  const handleTabClick = (index) => {
    setActiveTab(index);
  };


  return (
    <div>
      <div className="tabs">
        {React.Children.map(children, (child, index) => {
          return React.cloneElement(child, {
            active: activeTab === index,
            onClick: () => handleTabClick(index)
          });
        })}
      </div>
      <div className="tab-panels">
        {React.Children.map(children, (child, index) => {
          if (index === activeTab) {
            return child.props.children;
          }
          return null;
        })}
      </div>
    </div>
  );
};


const Tab = ({ active, onClick, label }) => {
  return (
    <div
      className={`tab ${active ? 'active' : ''}`}
      onClick={onClick}
    >
      {label}
    </div>
  );
};


const TabPanel = ({ children }) => {
  return <div className="tab-panel">{children}</div>;
};


export { Tabs, Tab, TabPanel };
    
        


Let's illustrate the Compound Components pattern with the code snippet above, This example is about building a Tabs component in ReactJS.

The Tabs component consists of a parent component called Tabs and child components called Tab and TabPanel.

The Tabs component will manage the active tab state and handle the interaction between the Tab and TabPanel components. The consumer of the Tabs component will be able to customize the appearance and behavior of the tabs by passing appropriate props.

In this example, the Tabs component acts as the parent component that manages the active tab state and handles the click events. It renders the Tab components and passes down the active state and click handler as props. It also renders the corresponding TabPanel based on the active tab index.

The Tab component represents an individual tab and receives the active state and click handler from the Tabs component. It renders the tab label and applies the active class based on the active state.

The TabPanel component represents the content associated with each tab. It renders the content within a panel only when the corresponding tab is active.

Consumers of the Tabs component can customize the appearance and behavior of the tabs by passing different labels and styles as props to the Tab components.



import React from 'react'
import { Tabs, Tab, TabPanel } from './Tabs';


const App = () => {
  return (
    <Tabs>
      <Tab label="Tab 1">
        <TabPanel>
          <h2>Content for Tab 1</h2>
          <p>This is the content of Tab 1.</p>
        </TabPanel>
      </Tab>
      <Tab label="Tab 2">
        <TabPanel>
          <h2>Content for Tab 2</h2>
          <p>This is the content of Tab 2.</p>
        </TabPanel>
      </Tab>
      <Tab label="Tab 3">
        <TabPanel>
          <h2>Content for Tab 3</h2>
          <p>This is the content of Tab 3.</p>
        </TabPanel>
      </Tab>
    </Tabs>
  );
};


export default App;;        

In this usage example, the Tabs component is used to create a set of tabs with corresponding content. Each Tab component represents a tab with a label, and the TabPanel component contains the content for each tab.

By using the Compound Components pattern, the Tabs component manages the active tab state and handles the interaction between the tabs and their associated content panels. Consumers can customize the appearance and behavior of the tabs by passing different labels and styles.

Finally

The Compound Components design pattern is a powerful technique for creating complex, reusable, and flexible components in ReactJS. By encapsulating related components within a parent component and coordinating their behavior and state, you can create cohesive units of functionality that are highly customizable and maintainable.

The Compound Components pattern promotes encapsulation, reusability, flexibility, and centralized state management. It allows for the composition of components with a clear interface and facilitates the customization of behavior and appearance.

By understanding and leveraging the Compound Components pattern, you can build more modular and maintainable ReactJS applications that are easier to understand, extend, and reuse.

To view or add a comment, sign in

More articles by Mohammed Abdo

Others also viewed

Explore content categories