Stas Sorokin
Stas Sorokin

Reputation: 3741

How to get the latest state value after using setState?

I'm toggling a Tooltip, and I want the tooltip to appear when the this.state.open is true then disappear when this.state.open becomes false.

I have tried many methods including prevState, debugging and bind.

Here is the code

//this button is clicked
<Button variant="contained" color="primary" onClick={this.buttonClick}>
    {person.username}
</Button>
//this function fires
buttonClick = e => {
        this.setState({ buttonEl: e.target });
        //the this.state.open in the console.log below persistently stay false even after it has changed in the setState's callback below to true(the message from the console:'after state changed: true').
        console.log(this.state.open);
        function toggleState(state, props) {
            return { ...state, open: !this.state.open }; //here I toggle the state
        }
        this.setState(toggleState, () => console.log('after state changed: ', this.state.open));
    };

Every time I measure this.state.open at the beggining of buttonClick() function I get false.

I expect this.state.open to be true on the second time I click on the button and enter buttonClick function, also I expect the tooltip to disappear.

Upvotes: 0

Views: 246

Answers (2)

daydreamer
daydreamer

Reputation: 92149

You should use the following variant of setState

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

as per the official documentation

This way once the changes are applied in an atomic way. Hope this helps

Upvotes: 2

Joss Classey
Joss Classey

Reputation: 1062

Your code is needlessly complex. From what I understand, you want to toggle the open property to be either true or false depending on a button click. And you want your tooltip's visibility to be tied to this state.

Below is a simple example of changing state with a button click and a tooltip that will only show when open is set to true:

Edit red-glade-25lku

const Tooltip = props => {
  return (
    <React.Fragment>
      <div
        hidden={!props.hidden}
        style={{
          width: "100px",
          height: "100px",
          backgroundColor: "black",
          margin: "auto"
        }}
      />
    </React.Fragment>
  );
};

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { open: false };
  }
  buttonClick = () => {
    this.setState(prevState => ({ open: !prevState.open }));
  };
  render() {
    return (
      <div className="App">
        <button onClick={this.buttonClick}>Toggle</button>
        <p>{`this.state = { open: ${this.state.open} }`}</p>
        <Tooltip hidden={this.state.open} />
      </div>
    );
  }
}

Upvotes: 2

Related Questions