Skip to main content

Compound Components

One commonly used and powerful design pattern for conditional rendering is the Compound Components pattern.

In this pattern, the parent component defines a set of child components that work together to render a more complex UI. Each child component is responsible for rendering a specific part of the UI and receives props from the parent component that allow it to be customized. By combining multiple child components together, the parent component can create a more complex UI with conditional rendering that is easy to use and customize.

Here's an example of how to use the Compound Components pattern for conditional rendering in TypeScript and React:

import React, { useState } from "react";

interface Props {
isLoggedIn: boolean;
children: {
loggedIn: React.ReactNode;
loggedOut: React.ReactNode;
};
}

interface State {
showDetails: boolean;
}

class MyComponent extends React.Component<Props, State> {
state = {
showDetails: false,
};

handleButtonClick = () => {
this.setState((prevState) => ({
showDetails: !prevState.showDetails,
}));
};

render() {
const { isLoggedIn, children } = this.props;
const { showDetails } = this.state;

return (
<div>
{isLoggedIn ? children.loggedIn : children.loggedOut}

<button onClick={this.handleButtonClick}>{showDetails ? "Hide details" : "Show details"}</button>

{showDetails && (
<div>
<p>Here are some details:</p>
<ul>
<li>Detail 1</li>
<li>Detail 2</li>
<li>Detail 3</li>
</ul>
</div>
)}
</div>
);
}
}

export default MyComponent;

// Usage:
<MyComponent isLoggedIn={isLoggedIn}>
{{
loggedIn: <p>Welcome, user!</p>,
loggedOut: <p>Please log in to continue.</p>,
}}
</MyComponent>;

In this example, we define a MyComponent class component that takes a isLoggedIn boolean prop and a children prop that contains two child components: loggedIn and loggedOut. Each child component is responsible for rendering the appropriate content based on the user's login status.

Inside the MyComponent class, we use the isLoggedIn prop to conditionally render either the loggedIn child component or the loggedOut child component.

We also have a button that toggles the display of some additional details. This button's text is conditionally rendered based on whether the showDetails state variable is true or false.

Finally, we use the showDetails state variable to conditionally render a div containing some details. This div is only shown if showDetails is true.

By using the Compound Components pattern, we can create a more flexible and reusable component that allows for easy customization of the content to be rendered based on the user's login status. This pattern also provides a clear and intuitive API for consumers of our component, making it easier to use and maintain.

Resources