简体   繁体   中英

React - this.setState doesn't work as expected until function is called a second time

I have a fairly basic function in my React component that isn't working as expected. The component itself is a nav bar for the top of the page. I'd like to implement a slide out menu for mobile screens triggered by a click on a hamburger icon that is inside the nav like so.

<a href="javascript:void(0)" onClick={this.toggleMenu.bind(this)}><i className="fa fa-bars" /></a>

For the moment I simply have this function set up to toggle a visible value between true and false , which I am calling from my hamburger.

toggleMenu() {
    console.log('Burger clicked... ', this.state.visible);
    this.setState({ visible: !this.state.visible });
    console.log('Visible changed.. ', this.state.visible); 
    var value = "A message from the burger...";
    this.props.sendData(value, this.state.visible);
  }  

The problem is this.setState({ visible: !this.state.visible }); doesn't switch from its initial value of false until the hamburger icon is clicked a second time.

Just for reference here is the component's constructor.

constructor() {
    super();
    this.state = {
      visible: false,
    };
  }

I'm relatively new to React so still finding my way around. If anyone could let me know how to resolve this issue I'd be very grateful. Thanks in advance!

React batches setState calls to increase performance, so calculating your new state by directly accessing the old state like you are doing might not work as expected, update your toggleMenu like this

toggleMenu() {
    console.log('Burger clicked... ', this.state.visible); 
    this.setState(prevState => {
        console.log('Visible changed.. ', !prevState.visible);
        var value = "A message from the burger...";
        this.props.sendData(value, !prevState.visible);
        return  {visible: !prevState.visible };
    });
}

Keep in mind that this.setState() is asynchronous. If you want something to happen after the new state is set, you'll need to include it as a callback function like so:

this.setState({
  visible: !this.state.visible
}, () => {
  // callback
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM