I'm creating a popover component for a UI in React. That component contains a button that triggers the popover to display. Because the button needs to be configurable--label, classes, properties--I need to pass down these configuration parameters to the child. There are two main ways I see this happening.
- Pass down label and props as attributes:
<PopoverComponent buttonLabel={label} buttonProps={buttonProps} />
- Pass down the actual button.
const button = <Button>Show</Button>;
<PopoverComponent button={button} />
The complication comes inside the popover. In order to place the element I need a ref
to the DOM node, so I must add props to the button element inside the PopoverComponent
. In React this is straightforward and standard in case 1. Just spread any custom props to the button. E.g., <Button ref="popoverButton" onClick={this.onClick} {...extraProps }>
. However, in case 2, we need to React.cloneElement
and mutate the props. E.g.,
// INSIDE popoverComponent
const { button } = this.props;
const extendedButton = React.cloneElement(
button,
Object.assign(
{},
button.props, {
ref: "popoverButton",
onClick: this.onClick,
}),
);
return <div className="popover-control">{ extendedButton }</div>;
Is it antipattern to use React.cloneElement
and modify props in child components in React?