The Three Levels of Reusability in React – Hacker Noon

Components that cannot be reused at all

There are a number of ways to build a button, and different team members probably have different preferences. I’ve seen developers rebuild a simple Button hundreds of times rather than build a single reusable button that can be reused across their application.

For example, sometimes I see buttons with specific business logic and styling baked-in. I’ve even seen some hard-coded text.

const ComparisonButton = ({ 
isDisabled,
icon,
width,
color,
region
}) => {
const color = isDisabled === true ? '#999999' : '#1274b8';
const btnClass = region === 'us' ? 'btn__blue : 'btn__red';
  return (

);
};

It can be used like this:

import { ComparisonButton } from './ComparisonButton
const ParentComponent = () => {
return
}

There are a few major problems with the way this Button component is implemented.

  1. Text is hardcoded in the Button. What happens if you need to internationalize your application, and the Button text needs to be in French?
  2. The Button knows about the Icon component. What happens if someone wants to use this Button without an Icon in it?

3. The Button’s styling is determined inside of it, rather than passed in as a prop. This makes the styles more difficult to override. What if you want to reuse the logic of the Button with slightly different styles?

This Button is really specific to its context. It can only be used in one scenario, even if it shares logic with all of the other buttons on the site. You can’t even pass whatever text you want into it!

Let’s say we wanted to refactor this into a component that could be reused within our application.

Components that can only be reused within an application

If we refactor the previous example to be reusable within our application, it needs to be much more generic.

const Button = ({ children, onClick, className, ...props }) => {   
return (

);
};

It can be used like this:

const ParentComponent = (props) => {
  const color = props.isDisabled === true ? '#999999' : '#1274b8';
const btnClass = props.region === 'us' ? 'btn__blue : 'btn__red';
const onClick = () => { // do something }
  
}

Now, Button doesn’t need to know about Icon. It’s very easy for another developer to reuse the Button in a scenario where the Icon isn’t present.

We’ve also moved the knowledge of what color the Icon should be when the button is disabled into the ParentComponent. Additionally, the ParentComponent manages how the Button should be styled based on region.

The logic inside of Button only deals with what it needs to know, while the application handles the business logic. That allows other developers working within the same repo as this app to reuse the button.

Components that can be shared between applications

Say your team expands, and you want all of the teams to provide a consistent experience to your users. You’re going to need to level-up to the third type of reusable component. You’ll build a library of reusable components that can be consumed by all of the teams you work with.

That library:

  1. Must be installable into other applications
  2. Must handle styling
  3. Must make styling easy to override
  4. Must have documentation

Your button will probably still look like it did before, but now, you’ll be importing it from your library, rather than from another file in your application.

How to actually build a reusable component library is a topic for another post, but if you’re trying to decide whether you’d like to take this project on, consider reading Should You Build a Reusable Component Library?

read original article here