12

Here is a summary of the code I have inside my React component:

getInitialState: function(){
  return{link:""}
},
onClick1: function(){
   this.setState({link:"Link1"});
   this.otherFunction();
},
onClick2: function(){
   this.setState({link:"Link2"});
   this.otherFunction();
},
otherFunction:function(){
     //API call to this.state.link
},
render: function(){
  return <div>
  <button1 onClick={this.onClick1}>Link1</button>
  <button2 onClick={this.onClick2}>Link2</button>
  //...some code to display the results of API call
  </div>
  }

The problem I have is that the first time I click the button, the otherFunction will run, but it will not have the updated value of myState. If I click a second time, then it works correctly.

2
  • setState is triggering the render; what is otherFunction and what state is it supposed to be updating? Commented Jan 14, 2016 at 22:22
  • there is another state for the API data. That is what the function is updating. I did not include it here because I didn't think it was related. Commented Jan 14, 2016 at 23:29

3 Answers 3

12

From the docs:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

If you want a function to execute after the state transition completes, pass it in as a callback:

onClick1: function() {
   this.setState({link:"Link1"}, this.otherFunction);
},
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the explanation. Unfortunately, putting the function as a callback does not work. EDIT: I have seen some examples and it sounds like it should work. Not sure why mine isn't. I will look it over again.
Somewhat unrelated, otherFunction might be unbound; this might be better: this.SetState(/*...*/, () => this.otherFunction() ).
2

Well, here I am answering my own question, for future reference. I figured it out. I removed this.otherFunction() from the onClick functions, and put it in componentWillUpdate. So it looks like this:

getInitialState: function(){
  return{link:""}
},
onClick1: function(){
   this.setState({link:"Link1"});
},
onClick2: function(){
   this.setState({link:"Link2"});
},
otherFunction:function(){
     //API call to this.state.link
},
componentWillUpdate(){
    this.otherFunction();
},
render: function(){
  return <div>
  <button1 onClick={this.onClick1}>Link1</button>
  <button2 onClick={this.onClick2}>Link2</button>
  //...some code to display the results of API call
  </div>
  }

Comments

1

If all that onClick does is change the state, then you shouldn't have two functions that do the same job. You should have the new value of the "link" state passed as an argument to the function "onClick" :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.