Too many props, it hurts πŸ˜“ thumbnail image
Neville Kati /

~ min read

Too many props, it hurts πŸ˜“

When starting a new project, it may seem straightforward to introduce a new prop to manage a specific behavior or style in your components. While this approach works initially, as the project scales, it becomes increasingly difficult to track what each prop controls. This adds unnecessary complexity and makes the component harder to maintain in the long run.

The Problem

Let us say you have been given a design and you plan on building a reusable button component that looks something like this:

React component tree

This button contains just a text and an icon to the left.

interface ButtonProps {
  text: string
  icon?: string
}

const Button = ({ text, icon }: ButtonProps) => {
  return (
    <button>
      {icon ? <Icon name={ icon} size={10} />}
      <span>{text}</span>
    </button>
  )
}

// and can be used assuch

<Button text="Add More" icon="plus" />

This is quite straightforward!

A week later the designer comes in and makes changes to the component and the component now needs to accept extra parameters, such as a right icon, left icon, and the size should be dynamic for each..

That's alot of changes πŸ˜“, we then decide to add extra props to accomodate these scenarios

const Button = ({ text, leftIcon, rightIcon, leftIconSize, rightIconSize }) => {
  return (
    <button>
      {leftIcon ? <Icon name={leftIcon} size={leftIconSize} />}
      <span>{text}</span>
      {rightIcon ? <Icon name={rightIcon} size={rightIconSize} />}
    </button>
  )
}

// and can be used assuch

<Button text="Add More" leftIcon="plus" rightIcon="plus" leftIconSize={10} rightIconSize={15}/>

We now have now moved from 2 props originally to 5 props, with the potential of growing even more. πŸ€¦πŸΎβ€β™‚οΈ

A better way: Compound Components πŸ’ͺ🏾

Compound components are a composition pattern that allows us to define individual parts of a component as independent components that work together as a cohesive unit. This approach offers flexibility, enabling developers to easily include or exclude specific sections of the component based on their needs. To easily understand this, you can think of select and option HTML elements and how they work.

Let us modify the Button example above using Compound components.


export const ButtonRoot = (props) => {
  return <button {...props}>{props.children}</button>
}

export const ButtonIcon = (props) => {
  return <Icon {...props} />
}

export const ButtonText = (props) => {
  return <span {...props}>{props.children}</span>
}

export const Button = {
  Root: ButtonRoot,
  Icon: ButtonIcon,
  Text: ButtonText,
}


// It can then be used assuch

<Button.Root>
 // Left Icon
 <Button.Icon icon="plus" size={10} />
 <Button.Text>Add More</Button.Text>
 // Right Icon
 <Button.Icon icon="plus" size={10} />
</Button.Root>

This approach provides a cleaner structure, is much more readable, maintainable and scalable.

You can learn more about this pattern here

Good luck! πŸ‘‹πŸ»