2

learning from some tutorial docs, I'm trying to update the counter (increment / reset) depending on the condition, below is the actual code on the tutorial

var CowClicker = React.createClass({
  getInitialState: function() {
    return {
      clicks: 10,
      val:1                   // this has been added by me
    };
  },

  onCowClick: function(evt) {
    this.setState({
      clicks: this.state.clicks + 1,
      val: this.state.val * this.state.clicks,  // code part in question
      }
    });
  },

  render: function() {
    return (
      <div>
        <div>Clicks: {this.state.clicks}</div>
        <div>Val: {this.state.val}</div>
        <img
          src="http://s3.bypaulshen.com/buildwithreact/cow.png"
          onClick={this.onCowClick}
          className="cow"
        />
        <p>Click the cow</p>
      </div>
    );
  }
});

ReactDOM.render(
  <CowClicker />,
  document.getElementById('container')
);

Now, I'm trying to put condition based reset as below but it won't work :

  onCowClick: function(evt) {
    this.setState({
      clicks: this.state.clicks + 1,
      alert(this.state.val),
      if(this.state.val > 1000000){ //this is not working
        val: 1,
      }else{
        val: this.state.val * this.state.clicks,
      }
    });
  },

This question might be way too obvious or stupid that's why I'm not getting a pointer on web as to where I'm wrong?
Can setState not operate on logical operators? Is it purely to set stuffs or play around with using function calls (e.g. links searched 1 | 2)?

RBT
  • 24,161
  • 21
  • 159
  • 240
NoobEditor
  • 15,563
  • 19
  • 81
  • 112

2 Answers2

3

You Provide

{
  clicks: this.state.clicks + 1,
  alert(this.state.val),
  if(this.state.val > 1000000){ //this is not working
    val: 1,
  }else{
    val: this.state.val * this.state.clicks,
  }
}

as a parameter which must either be an object or a function to your setState() call.

Your if is somewhere within the object, that can't work as far as I know :-)

Provide an object:

onCowClick: function(evt) {
  const val = this.state.val > 1000000 ? 1 : this.state.val * this.state.clicks;
  alert(this.state.val);
  this.setState({
    clicks: this.state.clicks + 1,
    val: val,
  });
},

Provide a function:

onCowClick: function(evt) {
  this.setState((prevState, props) => {
    const val = prevState.val > 1000000 ? 1 : prevState.val * prevState.clicks;
    return {
      clicks: prevState.clicks + 1,
      val: val,
    };
  });
},

Whereof the latter would be more correct, as you will refer to the current state and the first could refer to a outdated state.

flob
  • 3,760
  • 2
  • 34
  • 57
  • if i break down `const val = this.state.val > 1000000 ? 1 : this.state.val * this.state.clicks;` into `if` condition instead of ternary condition, it wont work, is there a reason to it? – NoobEditor Nov 22 '17 at 05:22
  • If you put the if at the very same position as the `const val = ` it should work. You can't put it inside the object declaration. Was that the problem? – flob Nov 23 '17 at 14:21
2

setState either accepts a new object (updater) or a callback.

this.setState({
  clicks: this.state.clicks + 1,
  val: this.state.val > 1000000 ? 1 : this.state.val * this.state.clicks,
})

as a callback example:

this.setState(prevState => ({
  ...prevState,
  clicks: prevState.clicks + 1,
  val: prevState.val > 1000000 ? 1 : prevState.val * prevState.clicks,
}))

Should you need to execute any other action right after state has been updated:

this.setState({
  clicks: this.state.clicks + 1,
  val: this.state.val > 1000000 ? 1 : this.state.val * this.state.clicks,
}, () => {
  // your next action
})

Please refer the ReactJS docs for more information.

Hemerson Carlin
  • 7,354
  • 1
  • 27
  • 38