I am currently building a dropdown button to learn React. I have made two onMouseEnter and onMouseLeave events in the parent div to make it visible when hovering it disappear when not. The problem is that those events only stick to parent.
How to make onMouseLeave in React include the child context? Or, how can I keep the state expand be true when hovering on children?
class DropDownButton extends React.Component {
constructor(){
super();
this.handleHoverOn = this.handleHoverOn.bind(this);
this.handleHoverOff = this.handleHoverOff.bind(this);
this.state = {expand: false};
}
handleHoverOn(){
if(this.props.hover){
this.setState({expand: true});
}
}
handleHoverOff(){
if(this.props.hover){
this.setState({expand: false});
}
}
render() {
return (
<div>
<div className={styles.listTitle}
onMouseEnter={this.handleHoverOn}
onMouseLeave={this.handleHoverOff}>
{this.props.name}
</div>
<div>
{React.Children.map(this.props.children, function(child){
return React.cloneElement(child, {className: 'child'});
})}
</div>
</div>
);
}
}
To show an element on hover in React: Set the onMouseOver and onMouseOut props on the element. Track whether the user is hovering over the element in a state variable. Conditionally render the other element based on the state variable.
Props is simply an abbreviation for properties. In React, we utilize props to send data from one component to another (from a parent component to a child component or multiple children components). They come in handy when you want the data flow in an app to be dynamic.
React. Children. toArray() changes keys to preserve the semantics of nested arrays when flattening lists of children. That is, toArray prefixes each key in the returned array so that each element's key is scoped to the input array containing it.
You have two different div
s in your DOM that don't overlap; I'll split up render
so it's more obvious:
render() {
return (
<div>
<div className={styles.listTitle}
onMouseEnter={this.handleHoverOn}
onMouseLeave={this.handleHoverOff}>
{this.props.name}
</div>
<div>
{React.Children.map(this.props.children, function(child){
return React.cloneElement(child, {className: 'child'});
})}
</div>
</div>
);
}
The div
that has the onMouseLeave
attached to it does not contain the children; so, when the mouse moves to hover on a child, it leaves the div
and this.handleHoverOff
is called.
You might consider using CSS to hide the children if they shouldn't be displayed, or conditionally rendering them:
render() {
return (
<div className={styles.listTitle}
onMouseEnter={this.handleHoverOn}
onMouseLeave={this.handleHoverOff}>
{this.props.name}
{this.state.expanded && this.renderChildren()}
</div>
);
},
renderChildren() {
return (
<div>
{React.Children.map(this.props.children, function(child){
return React.cloneElement(child, {className: 'child'});
})}
</div>
);
}
By using the on mouse leave instead of mouse out and blocking the event on the children I got it reliably working no matter how fast I move through my list items.
https://stackoverflow.com/a/18837002/3302764
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With