8-writing-reusable-components-in-react-with-typescript-and-styled-components.html

Writing Reusable Components in React with TypeScript and Styled Components

In the world of web development, code reusability is a cornerstone of efficiency and maintainability. React, combined with TypeScript and Styled Components, provides a powerful framework for creating reusable UI components. In this article, we’ll explore how to leverage these technologies to build components that not only enhance your development workflow but also ensure a consistent and scalable design system.

What Are Reusable Components?

Reusable components are modular pieces of code that can be utilized across different parts of an application without rewriting the same logic. They encapsulate their functionality and styles, making them easy to incorporate into various contexts. This approach significantly reduces duplication, making your codebase cleaner and more manageable.

Why Use TypeScript with React?

TypeScript is a superset of JavaScript that adds static typing. When used with React, it provides several benefits:

  • Type Safety: Catch errors at compile time rather than runtime.
  • IntelliSense: Enhanced code completion and documentation support in IDEs.
  • Improved Collaboration: Clearer contracts for components that make it easier for teams to work together.

Benefits of Styled Components

Styled Components is a library that allows you to write CSS directly within your JavaScript files. Its key benefits include:

  • Scoped Styles: Avoid global CSS conflicts by scoping styles to components.
  • Dynamic Styling: Easily change styles based on props.
  • Theming: Create a cohesive design system with theme providers.

Getting Started

Setting Up Your React Environment

To start building reusable components with React, TypeScript, and Styled Components, ensure you have Node.js installed. You can create a new React app with TypeScript using Create React App:

npx create-react-app my-app --template typescript
cd my-app

Next, install Styled Components and its TypeScript types:

npm install styled-components
npm install @types/styled-components --save-dev

Creating a Reusable Button Component

Let’s create a reusable button component that can be styled dynamically based on props.

Step 1: Define the Button Component

Create a new file named Button.tsx in the src/components directory:

import React from 'react';
import styled from 'styled-components';

interface ButtonProps {
  primary?: boolean;
  onClick?: () => void;
}

const StyledButton = styled.button<ButtonProps>`
  background: ${({ primary }) => (primary ? 'blue' : 'gray')};
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;

  &:hover {
    opacity: 0.8;
  }
`;

const Button: React.FC<ButtonProps> = ({ primary, children, onClick }) => {
  return (
    <StyledButton primary={primary} onClick={onClick}>
      {children}
    </StyledButton>
  );
};

export default Button;

Step 2: Using the Button Component

Now that we have our Button component, let’s use it in App.tsx:

import React from 'react';
import Button from './components/Button';

const App: React.FC = () => {
  const handleClick = () => {
    alert('Button Clicked!');
  };

  return (
    <div>
      <h1>Reusable Button Component</h1>
      <Button primary onClick={handleClick}>
        Primary Button
      </Button>
      <Button onClick={handleClick}>
        Secondary Button
      </Button>
    </div>
  );
};

export default App;

Step 3: Adding More Functionality

You can further enhance your Button component by adding more props, such as disabled, size, or loading states. Here’s how to add a loading state:

Update Button Component

interface ButtonProps {
  primary?: boolean;
  onClick?: () => void;
  loading?: boolean;
}

const StyledButton = styled.button<ButtonProps>`
  background: ${({ primary }) => (primary ? 'blue' : 'gray')};
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: ${({ loading }) => (loading ? 'not-allowed' : 'pointer')};
  opacity: ${({ loading }) => (loading ? 0.5 : 1)};
`;

const Button: React.FC<ButtonProps> = ({ primary, children, onClick, loading }) => {
  return (
    <StyledButton primary={primary} onClick={loading ? undefined : onClick} disabled={loading}>
      {loading ? 'Loading...' : children}
    </StyledButton>
  );
};

Step 4: Implementing in Your App

Now you can use the loading prop in your App.tsx:

const App: React.FC = () => {
  const [loading, setLoading] = React.useState(false);

  const handleClick = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 2000); // Simulate a network request
  };

  return (
    <div>
      <h1>Reusable Button Component</h1>
      <Button primary onClick={handleClick} loading={loading}>
        Submit
      </Button>
    </div>
  );
};

Conclusion

Creating reusable components in React with TypeScript and Styled Components not only streamlines your development process but also enhances the maintainability of your codebase. By encapsulating functionality and styling, you ensure that your components are versatile and easy to manage.

Key Takeaways:

  • Embrace TypeScript: Ensure type safety and improve developer experience.
  • Utilize Styled Components: Write scoped, dynamic styles with ease.
  • Build Versatile Components: Enhance usability by adding props for customization.

By following the steps outlined in this article, you can start building your own reusable components that can be shared across your React applications, ultimately leading to a more efficient development process. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.