React Extension components
Tags: javascript, react, webdev, programming
Published: 2021-02-18 13:24:12

---
title: React Extension components
tags:
 - javascript
 - react
 - webdev
 - programming
published: true
---
# Overview

Reusing React components can be tricky. You need to think twice before you try to extend a reusable component, otherwise, it might become a massive beast which can no longer be tamed. Talking from experience, you need to come up with a plan about how to extend your reusable components before you start playing with files long thousands of lines of code, which once used to be a simple Button component. This is when the idea for React extensions was born. 

The idea of having extensions is to be able to build different components which can reuse each other. It was inspired by the inheritance mechanism, which you can apply on a class upon another class to retain similar implementation. This way you will have small components built with single responsibility in mind which will be easy to scale up and maintain later on. 

# Building React Extensions

For this example, I will build a reusable `Button` component which I will extend later on with additional features.

Let's start with a simple `Button`:

```jsx
// Different button variants which will apply different styling
const btnVariants = {
  primary: "primary",
  danger: "danger",
  tertiary: "tertiary",
};

// Variant styles
const variantStyles = {
  [btnVariants.primary]: {
    background: "#1890ff",
  },
  [btnVariants.danger]: {
    background: "#f81d22",
  },
  [btnVariants.tertiary]: {
    background: "#fff",
    color: "#000",
  },
};

function BaseButton({ variant, ...props }) {
  const btnStyle = {
    color: "#fff",
    border: "none",
    padding: "5px 10px",
    ...variantStyles[variant],
  };

  return <button {...props} style={btnStyle} />;
}
```

`Button` component which has a `variant` prop to apply different styling. You can think of this component as the **Base** component from which each extension will inherit from. This component will have the functionality that every component is supposed to have and nothing else. It's very important to correctly decouple the different functionalities to build a maintainable component.

Let's build an extension which will easily allow adding an icon to the `BaseButton`. To do this, let's create a new React component which will reuse the `BaseButton` and build on top of it.

```jsx
const container = {
  display: "flex",
  alignItems: "center",
};

function IconButton({ icon = "", iconPosition = "left", ...props }) {
  const iconStyle = {
    width: 20,
    height: 20,
    ...(iconPosition === "left" ? { marginRight: 10 } : { marginLeft: 10 }),
  };

  const Icon = <img src={icon} style={iconStyle} />;

  return (
    <Button {...props}>
      <div style={container}>
        {iconPosition === "left" && Icon}
        {props.children}
        {iconPosition === "right" && Icon}
      </div>
    </Button>
  );
}
```
The IconButton component applies two new props - `icon` and `iconPosition` which are relevant to this new component. The `BaseButton` doesn't need to know about them. This component is reusing the `BaseButton` without neglecting any of its props but building on top of. 

You can assign the extensions to the base component like you are assigning a property to an object. This will allow to easily access any of the extensions while using the component.

```jsx
const Button = BaseButton;
Button.WithIcon = IconButton;

<Button variant="primary">My Button</Button>
<Button.WithIcon variant="tertiary" icon="random-path/icon.jpg">My Button with Icon</Button.WithIcon>
```

---
This pattern allows building truly reusable components without the worry that they will grow to a point where we won't be able to maintain them. I hope this will find out well and will help you while working with React. Let me know what you think about this pattern.