0

I am a newbie learning to build a rpg game with React.js, and I found this part very confusing.

I am trying to update life with onClick and when life<damage, the object player is dropped. So the html looks like this:

enter image description here

The current player is generated like this:

<h4>You are: {this.props.targets[this.props.playerindex].name}</h4>

I use these code to handle attack and update the index:

handleAttack(index1,id2){
    let players = this.state.players.slice();
    let index2 = players.findIndex(x => x.id === id2);
    let damage = players[index1].damage;
    let life = players[index2].life;
    console.log("Before(length):"+this.state.players.length);
    if (life>damage){
        players[index2].life = life-damage;}
    else {players=players.filter(player => player.id !== id2);}
    this.setState({players},()=>{console.log("After(length):"+this.state.players.length);
                                 this.handleUpdateIndex();});
}

handleUpdateIndex(){
    console.log("Before:"+this.state.playerindex);
    let index=this.state.playerindex;
    let length=this.state.players.length;
    console.log("BeforeUpdate(length)"+this.state.players.length);
    if(index<length-1)
    {this.setState({playerindex:index+1},() => {console.log("After:"+this.state.playerindex);});}
    else{this.setState({playerindex:0},() => {console.log("After:"+this.state.playerindex);});}
    this.forceUpdate();
}

But sometimes the index will increment while it should not, and causes this:

enter image description here

I think it might be the asynchronous behavior of setState, but I don't know how should I solve this problem.

If you have a solution or another way to achieve the expected behavior, please help!

Code here:

App.js: https://ghostbin.com/paste/e9wjg

Attack.js: https://ghostbin.com/paste/3zbwk

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
Shukai Ni
  • 457
  • 2
  • 6
  • 17
  • assign a conditional check like `

    You are: {this.props.targets && this.props.targets[this.props.playerindex] && this.props.targets[this.props.playerindex].name}

    `
    – Shubham Khatri Jun 16 '17 at 15:06
  • @ShubhamKhatri could you please explain this code? Also it stops the Error Massage, but sometimes the last player(Spud) is skipped. – Shukai Ni Jun 16 '17 at 15:11
  • In fact it's not the last player that is skipped but the next player after one player is killed – Shukai Ni Jun 16 '17 at 15:13
  • so what it is doing is checking if `this.props.targets` exits then checks if `this.props.targets[this.props.playerindex]` exists and then only returns the value else returns null. If its not rendering the last value then check what index you get – Shubham Khatri Jun 16 '17 at 15:13
  • Thanks, I find the mistake after your remind – Shukai Ni Jun 16 '17 at 15:20

1 Answers1

0

I know what i am wrong:

when I am dropping a object, I should move the index back:

   if (life>damage){
        players[index2].life = life-damage;}
    else {players=players.filter(player => player.id !== id2);
          this.setState({playerindex:this.state.playerindex-1});}

This problem is solved, however please give me advice on this project if you like!

Shukai Ni
  • 457
  • 2
  • 6
  • 17
  • check this when you use setState https://stackoverflow.com/questions/44492678/when-does-reacts-setstate-change-the-state/44493095#44493095 – Shubham Khatri Jun 16 '17 at 15:22