How to make onMouseLeave in React include the child context?
Asked Answered
B

2

17

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>
     );
}
}
Bidwell answered 16/8, 2015 at 14:12 Comment(0)
C
11

You have two different divs 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>
    );
}
Conversationalist answered 16/8, 2015 at 16:6 Comment(1)
It works. I did a stupid mistake, and the conditional rendering is useful for me too. Thanks!Bidwell
I
6

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://mcmap.net/q/117685/-prevent-onmouseout-when-hovering-child-element-of-the-parent-absolute-div-without-jquery

Impostume answered 19/9, 2017 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.