Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to spread props over a component without overriding specified attributes?

I'm creating a bunch of base components for an app and I'd like to write as little customization as possible. Instead opting to pass on the attributes of the parent to the child. I have a bunch of buttons that defined like this:

export const PrimaryButton = (props) => {
    return (
        <button className={style.primary} {...props}>{props.children}</button>
    )
};

However, when I do this, if the button is declared like this:

<PrimaryButton className="someClass">Submit</PrimaryButton>

the class name on the parent overrides the classname provided in the component. What I'd like is for them to work together. I have figured out that I can do this by declaring the props I want individually like this:

export const PrimaryButton = (props) => {
    props.className = props.className + style.primary;
    return (
        <button className={style.primary + props.className}>{props.children}</button>
    )
};

Since I'm no longer spreading things over though I now have to declare anything like onClick manually and this seems messy because I don't know what events it may need to have in the future and I'd like it to be as reusable as possible without needing to be changed all the time.


1 Answers

Use destructuring with rest to separate the className and children from the props you wish to spread:

export const PrimaryButton = ({ className = '', children, ...props }) => (
  <button className={`${style.primary} ${className}`} {...props}> 
  {children}
  </button>
);
like image 88
Ori Drori Avatar answered Nov 27 '25 13:11

Ori Drori



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!