0

In a component AddWordPartButton's class, I initialized a state isHovered to false and used onMouseEnter and onMouseLeave to change its value.

Here's the mapping I want (which seems to me that I've defined in the code):

  • onMouseEnterisHovered = true
  • onMouseLeaveisHovered = false

What happens is the opposite of what I expect to happen and I don't see any reason for this behavior. Here's the mapping that seems to occur:

  • onMouseEnterisHovered = false
  • onMouseLeaveisHovered = true

I use AddWordPartButton in another component with nothing that should be affecting its behavior, calling with this <AddWordPartButton /> inside a render function of the other component - it works perfectly fine except for this.

This is the code:

import React from 'react;

class AddWordPartButton extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            isHovered: false,
        };
        this.onMouseEnterHandler = this.onMouseEnterHandler.bind(this);
        this.onMouseLeaveHandler = this.onMouseLeaveHandler.bind(this);
    } 

    onMouseEnterHandler() {
        this.setState({isHovered: true});
        console.log(this.state); //logs false
    }

    onMouseLeaveHandler() {
        this.setState({isHovered: false});
        console.log(this.state); //logs true
    }

    render() {
        <div className={classes.addWordPartButton__Container} 
            onMouseEnter={this.onMouseEnterHandler}
            onMouseLeave={this.onMouseLeaveHandler}
        >
        </div>


    }

}

Why is this happening and how can I fix it?

Gal Grünfeld
  • 800
  • 3
  • 9
  • 32

1 Answers1

3

set state is async, use this instead, the callback argument to the setState func will fire after it sets state. It is opposite bc you are always logging one step behind the new state update.

onMouseEnterHandler() {
    this.setState(() => ({isHovered: true}), () => console.log(this.state));
}

onMouseLeaveHandler() {
    this.setState(() => ({isHovered: false}), () => console.log(this.state));
}
Tholle
  • 108,070
  • 19
  • 198
  • 189
Eric Hasselbring
  • 1,374
  • 1
  • 10
  • 18
  • Thanks, I didn't know it's async. It solved my issue. – Gal Grünfeld Feb 18 '19 at 21:29
  • Saying it is async is not quite accurate. Much of the time it is sync. "[...] This doesn't mean it will always be asynchronous - it mainly means that you just can't depend on it being synchronous." https://stackoverflow.com/a/48438145/2054731 – ArneHugo Feb 18 '19 at 21:47
  • no it is 100% async, don't confuse people and say it "behaves synchronous" most of the time – Eric Hasselbring Jun 04 '21 at 12:22