One of the most common tasks in a React project is creating reusable components that are flexible and easy to maintain.
In this post, Iβll share a quick and practical pattern to build typed, reusable components in React + TypeScript β keeping it simple and effective for real-world use.
β The Problem: Reusability + Type Safety
Imagine you need a button component that supports different variants (like primary
, secondary
), handles clicks, and accepts any content inside it. How would you type it properly?
Hereβs a clean way and efficient way to do it:
π» The Solution: Union Types + React Props
type ButtonProps = {
variant?: 'primary' | 'secondary';
onClick: () => void;
children: React.ReactNode;
};
export const Button = ({ variant = 'primary', onClick, children }: ButtonProps) => {
return (
<button className={`btn ${variant}`} onClick={onClick}>
{children}
</button>
);
};
βοΈ Why this works great?
-
variant
is defined as a union type ('primary' | 'secondary'
), making them type-safe and auto-completed by your editor. -
children
allows flexibility to pass any content (like icons or text). - Default value for variant simplifies usage.
- Easy to extend β just add more variants as needed.
π Usage Example:
<Button onClick={() => console.log('Clicked!')}>
Click me
</Button>
<Button variant="secondary" onClick={() => alert('Secondary clicked')}>
Secondary Action
</Button>
π‘ Pro Tip:
Want to add styled-components or CSS Modules? You can map variant
directly to class names or styled variants like this:
<Button variant="secondary" onClick={() => alert('Secondary Clicked!')}>
Secondary Action
</Button>
const StyledButton = styled.button<{ variant: 'primary' | 'secondary' }>`
background: ${({ variant }) => (variant === 'primary' ? 'blue' : 'gray')};
color: white;
padding: 10px 20px;
`;
This is a simple pattern to keep React components clean, flexible, and maintainable β something that can help any Front-End Developer in daily work.
π How do you handle reusable components in your projects? Share your approach in the comments! π
Top comments (0)