Why ? An anonymous function should be passed to `setState`

Tell us what’s happening:
I’ve read the solution but still kinda confused why should i pass anonymous function to setState ? In my defend my code works well. Is there any side effects from not doing so?(pass anonymous function to setState)

Can i have an explanation here? Sorry if i missed anything, i’m not a native english speaker so the chance i missed is pretty high. Thanks ^^

Your code so far


class MyComponent extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    visibility: false
  };
  // change code below this line
  this.toggleVisibility = this.toggleVisibility.bind(this)
  // change code above this line
}
// change code below this line
toggleVisibility(){
  if (this.state.visibility==false){
    this.setState({visibility: true})
  }
  else this.setState({visibility: false})
}
// change code above this line
render() {
  if (this.state.visibility) {
    return (
      <div>
        <button onClick={this.toggleVisibility}>Click Me</button>
        <h1>Now you see me!</h1>
      </div>
    );
  } else {
    return (
      <div>
        <button onClick={this.toggleVisibility}>Click Me</button>
      </div>
    );
  }
}
};

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36.

Challenge: Use State to Toggle an Element

Link to the challenge:

1 Like

Sometimes you might need to know the previous state when updating the state. However, state updates may be asynchronous - this means React may batch multiple setState() calls into a single update. This means you can’t rely on the previous value of this.state or this.props when calculating the next value.

so i did this and passed, um… turns out the test was testing whether a function exist in the setState

toggleVisibility(){
    if (this.state.visibility==false){
      this.setState(state=>({visibility: true}))
    }
    else this.setState(state =>({visibility: false}))
  }

It’s a good question. Take this example from react docs:

incrementCount = ( ) => this.setState({count: this.state.count + 1});

handleSomething() {
  // Let's say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // When React re-renders the component, `this.state.count` will be 1, but you expected 3.
}

And the reason is everytime this.state.count is read from the rendered value, so we are doing 0+1. 0+1, 0+1, and the final value will be 1.

If you want this.state.count to be updated properly, use the state, like so:

incrementCount = ( ) => this.setState(s=>{count: s.count + 1});

In your code, the value does not depend on sequential values of state, you read the rendered value, and set up a new object.

Hope this makes sense.

2 Likes

Thanks it’s a very good example (^^), sometimes i need example to fully grasp what’s going on. This React course is harder for me because of the language barrier. It’s getting more complex and takes more time to fully comprehend. One of the motivation to not give up is because of people like you who went out of their way just to help others learn. Thank you

@danzel-py Glad it helped. You might enjoy this resource.

I’ve added a working example here, where you can click a button, and it should append 2 bye byes, but just one is appended.

On the dark side, if you modify what I wrote using this.state.greeting+='bye' instead, it will work as any normal object update. I have no clue why is it so.

and how using a function helps with that? I mean how using a function can update the latest value and not the regular way of updating? What is the difference?