I've to extend the default onClick functionality on the button. If a user clicks on it the user's onClick should trigger, but I also have to extend it with triggering my own function with the user's onClick.
I've tried two approaches
I'm not able to figure out which one to choose. Why choose one over the other? Which one is efficient?
Live Demo
App.jsx
import "./styles.css";
import Wrap from "./Wrap";
import EnhancedButton from "./Button";
export default function App() {
function defaultOnClick() {
console.log("default on click");
}
return (
<div className="App">
<Wrap>
<button onClick={defaultOnClick}> count </button>
</Wrap>
<EnhancedButton onClick={defaultOnClick}>
click from enhanced button
</EnhancedButton>
</div>
);
}
Button.jsx
import React from "react";
import HOC from "./HOC";
function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
export default HOC(Button);
Wrap.jsx
import React from "react";
export default function WrapWithOnclick(props) {
const { children } = props;
function customWrapOnclick() {
console.log("customWrapOnclick");
}
return (
<>
{React.Children.map(children, (child) => {
return React.cloneElement(child, {
onClick: (e) => {
customWrapOnclick(e);
child.props.onClick && child.props.onClick(e);
}
});
})}
</>
);
}
HOC.jsx
export default function HOC(Component) {
return function ModifiedComponent(props) {
const { children, onClick: hocOnClick, ...rest } = props;
function customHOCOnclick() {
console.log("customHOCOnclick");
}
return (
<>
<Component
onClick={(e) => {
customHOCOnclick(e);
hocOnClick && hocOnClick();
}}
{...rest}
>
{children}
</Component>
</>
);
};
}
I don't like the cloneElement approach neither the HOC to be honest. What I would do is this:
import React from "react";
function Button({ children, onClick }) {
const localOnclick = () => {
//... do stuff ...
onClick && onClick()
}
return <LibraryButton onClick={localOnclick}>{children}</LibraryButton>;
}
export default Button;
It's pretty straight forward and very simple. Does it cover your case?