0

After calling this.setState the talents property still holds the old value:

onTalentModalCheckboxChange(e) {
  debugger;
  var talent = JSON.parse(e.target.dataset.talent);
  talent.checked = !talent.checked;

  if (this.maximumSelectedTalentsReached() && talent.checked) return;

  const talentIndex = this.state.talents.findIndex(t => t.Id == talent.Id);
  let updatedTalents = [...this.state.talents];
  updatedTalents[talentIndex] = talent;

  this.setState({ talents: updatedTalents });

  // this method (setSearchResultsTotal) uses this.state.talents, 
  // but the talent that is updated here, is not updated. 
  // It still has the 'old' checked value
  this.setSearchResultsTotal();
}

The talents property contains a list of Talent objects, which all have the checked property. My problem is that when setting the updated talent object

What am I missing here?

dance2die
  • 35,807
  • 39
  • 131
  • 194
Martijn
  • 24,441
  • 60
  • 174
  • 261
  • 1
    maybe this could help you, https://stackoverflow.com/questions/36085726/why-is-setstate-in-reactjs-async-instead-of-sync – Raghav Garg Sep 28 '18 at 20:31

2 Answers2

2

setState is asynchronous meaning the change doesn't happen immediately. So any function that uses state, needs to be called after the setState call completes. There are two ways to do this: use componentDidUpdate to fire off the function if this.state.talents is different than prevState.talents. Or, use the setState callback to call the function:

onTalentModalCheckboxChange(e) {
  debugger;
  var talent = JSON.parse(e.target.dataset.talent);
  talent.checked = !talent.checked;

  if (this.maximumSelectedTalentsReached() && talent.checked) return;

  const talentIndex = this.state.talents.findIndex(t => t.Id == talent.Id);
  let updatedTalents = [...this.state.talents];
  updatedTalents[talentIndex] = talent;

  // Only call this.setSearchResultsTotal after state has finished updating
  this.setState({ talents: updatedTalents }, () => this.setSearchResultsTotal(); );

}
Chase DeAnda
  • 15,963
  • 3
  • 30
  • 41
0

this.setState({ talents: updatedTalents }, () => {
  this.setSearchResultsTotal();
});

try calling ur method like this , it will work

Beckham_Vinoth
  • 701
  • 2
  • 13
  • 39
  • 1
    For the sake of explanation, what this is doing is registering an anonymous callback to make sure that `setSearchResultsTotal` is called after the state updates. – mhatch Sep 28 '18 at 20:51