Reputation: 27
I have a React function component, where I get another component in props. Something like this:
function ChildComponent({cmp}) {
// Here onClick handlers should be added [for example:
// () => console.log("clicked")] to all
// elements in cmp of class .clickable
return ...
}
function ParentComponent() {
return (
<ChildComponent cmp={<div><button>Non-clickable</button><button className="clickable">Clickable</button></div>} />
)
}
So how to add event handlers dynamically to elements with class clickable in the cmp props variable in the ChildComponent? Thank you in advance for your help.
Upvotes: 0
Views: 88
Reputation: 3644
This uses Children API that allows you to modify children's props based on its current props.
The ChildComponent will first loop through its current children, look for clickable
className
props and add onClick
handler to its props.
The recursion loop allows nested children to work too.
function ChildComponent({ cmp }) {
const handleOnClick = () => {
alert("Clicked");
};
const childrenMap = (child) => {
if (child.props) {
const newProps = Object.assign({}, child.props);
const { children, className } = newProps;
if (className && className.split(' ').some(cn => cn === 'clickable')) {
newProps.onClick = handleOnClick;
}
if (children) {
newProps.children = Children.map(children, childrenMap);
}
return cloneElement(child, newProps);
}
return child;
}
return Children.map(cmp, childrenMap);
}
function ParentComponent() {
return (
<ChildComponent
cmp={(
<div>
<button>Non-clickable</button>
<div>
<div>
<button className="clickable">Clickable</button>
</div>
</div>
<button className="clickable">Clickable</button>
</div>
)}
/>
);
}
Upvotes: 1