I will briefly go over this tutorial, with an example ErrorAlert
component.
The Problem
When creating reusable components people will naturally feel passing what the component needs as props would be right, but over time that component would become this:
<ErrorAlert
data={...}
type={...}
closeIcon={...}
className={...}
onInit={...}
onClose={...}
/>
You don't need me to tell you the disadvantages of this approach in the long run.
The Solution
import { IonIcon } from "@ionic/react";
import { alertCircleOutline } from "ionicons/icons";
import React from "react";
interface IEssentials {
className?: string;
}
const Body: React.FC<IEssentials> = ({ children, className, ...rest }) => {
return (
<div className={"p-4 text-sm text-red-700 bg-red-100 rounded-lg dark:bg-red-200 dark:text-red-800" + " " + className} {...rest} role="alert">
{children}
</div>
);
};
const Text: React.FC<IEssentials> = ({ children, className, ...rest }) => {
return (
<div className={"flex items-center gap-1" + " " + className} {...rest}>
<IonIcon icon={alertCircleOutline} />
<div>{children}</div>
</div>
);
};
export const ErrorAlert = { Body, Text };
Usage
import { ErrorAlert } from "./ErrorAlert.tsx"
const data = [...];
const App: React.FC = () => {
return (
<div>
<ErrorAlert.Body>
{data.map((dataItem) => (
<ErrorAlert.Text>
{dataItem}
</ErrorAlert.Text>
))}
</ErrorAlert.Body>
</div>
)
}
Advantages of this approach
- Open/Closed principle (SOLID): It should be open to extend but closed for modification.
- Single Responsibility Principle (SOLID): Individual child components should have a single responsibility or perform a single function, this approach makes it easier to extend without having to modify the whole component.
- Decoupling enables adding explicit functionalities based on requirements.
- Easy refactoring.
Top comments (0)