DEV Community

Gunnar Halen
Gunnar Halen

Posted on

How to Create a Reusable React + TypeScript Component (Simple and Clean)

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

βš™οΈ 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>
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ 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>
Enter fullscreen mode Exit fullscreen mode
const StyledButton = styled.button<{ variant: 'primary' | 'secondary' }>`
  background: ${({ variant }) => (variant === 'primary' ? 'blue' : 'gray')};
  color: white;
  padding: 10px 20px;
`;
Enter fullscreen mode Exit fullscreen mode

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)