No Time Dad

A blog about web development written by a busy dad

Creating Reusable React Buttons

Creating reusable react buttons can be a huge time savings in a project. Taking a generic button component and passing style props to it is likely the best way to accomplish this, but I’m sure there are many other ways. Some more complex than others.

I’ve written previously about creating a basline button, and I like that example so I’ll be using it here too. The basic idea is that I’m starting with a clean, mostly unstyled button, then dynamically passing different styles to it to change how it looks and behaves.

The baseline button mentioned above uses a separate css file for the styles. For this example I’m going use the style attribute to ovverride some of the default styles. This’ll make it easier for me to pass new styles to the button component without having to modify the css or do other strange things with conditionals to get the button working.

Example code

Below is an example of what the baseline button will look like and it’s corresponding code.

// button.jsx
import React from "react"
import * as styles from "./button.module.css"

export const Button = ({ style, text }) => {
  return (
    <button className={styles.button} type="button" style={{ ...style }}>
      {text}
    </button>
  )
}
/* button.module.css */
.button {
  background-color: #fff;
  border-color: #dbdbdb;
  border-width: 1px;
  color: #363636;
  border-radius: 0.5rem;
  padding: 1rem 1.5rem;
}

.button:hover {
  border-color: #b5b5b5;
}

.button:focus {
  outline: none;
  border-color: #363636;
  color: #363636;
  box-shadow: 0 0 0 0.125em rgba(156, 157, 161, 0.25);
}

The basic idea with this Button component is that it takes a prop called style which should be an object containing any styles I want to apply or override. The object should contain the properties in the proper React syntax or they’ll cause an error. For example backgroundColor vs background-color. The latter causing the error.

Something worth noting is that there isn’t easy way to change the :hover and :focus styles using this approach. I’m more or less stuck with the colors you set in the Button component using pure css. There are some clever things I could do using scss or css in js, but I won’t be going into them here.

The good news it that I can modify any of the .button selector properties. If I wanted a red button with white text, I’d just need to pass those values as a prop to the style attribute.

<BaselineButton
  style={{ backgroundColor: "red", color: "white" }}
  text="Button"
/>

Maybe I want to change the border color and border width for this component. It’s as easy as passing the style with the borderColor and borderWidth properties.

<BaselineButton
  style={{ borderColor: "red", borderWidth: "3px" }}
  text="Button"
/>

Being able to create reusable react buttons opens up a lot of possibilities. Not being able to set the :focus, :hover, or other pseudo-classes is definitely a drawback to this approach, but in my experience it hasn’t been a huge issue so far.