Reputation: 235
I'm trying to write a Higher-order Component which provide a hover property to a component. But I can't make it work with any type of component.
My HOC
function withHover(WrappedComponent) {
return class extends Component {
state = {
hover: false
}
onMouseEnter(){
this.setState({hover: true});
}
onMouseLeave(){
this.setState({hover: false});
}
render() {
return (
<div onMouseEnter={this.onMouseEnter.bind(this)} onMouseLeave={this.onMouseLeave.bind(this)}>
<WrappedComponent {...this.props} hover={this.state.hover}/>
</div>
)
}
}
}
My problem is that I have to wrap the component inside a div for the OnMouse
events to work. But when I want, for example, make a <tr>
inside a <table>
hoverable the <tr>
will be wrapped into a <div>
which break the <table>
logic.
I have thought of passing the HOC's OnMouse
events handlers to the wrapped component and call them inside it, but that is not quite convenient because the aim of all this is to save developpement time
So my question is : How to rewrite this HOC to avoid wrapping the initial component inside a <div>
?
Thanks for your time
Upvotes: 0
Views: 589
Reputation: 1383
You can just render WrappedComponent
from your HOC and passs onMouseEnter
and onMouseLeave
functions as props and then use them in wrapped components by spread operator on props
Code be like:
function withHover(WrappedComponent) {
return class extends Component {
state = {
hover: false
}
onMouseEnter = () => {
this.setState({hover: true});
}
onMouseLeave = () => {
this.setState({hover: false});
}
render() {
return <WrappedComponent onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} {...this.props} hover={this.state.hover}/>
}
}
}
const TableRow = props => {
return (
<tr {...props}>
{props.children}
</tr>
)
}
const TableRowWithHover = withHover(TableRow);
Upvotes: 2
Reputation: 36564
Wrap the child component in fragment in parent Component
pass the events to the child elm
Child Elm
class Child extends Component {
render() {
return (
<div
onMouseLeave={this.props.onMouseLeave || null}
onMouseEnter={this.props.onMouseEnter || null}
>
This is a child Component
</div>
);
}
}
Parent Component(wrapper)
import Child from './child';
class Parent extends Component {
state = { }
onMouseEnter = () =>{
console.log("mosuse Entered child")
}
onMouseLeave = () =>{
console.log("mosuse left child")
}
render() {
return (
<>
<Child onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}></Child>
</>
);
}
}
Upvotes: 1