Jota
Jota

Reputation: 865

Loop for with loop infinite using Break? ReactJs

What happens: I have these two variables: ScorePlayer andScoreDealer, which are the result of a sum of the elements contained in the main array of each of them cardsPlayer andcardsDealer.

And what I want is to do the verification. If the value of the ScoreDealer variable is less than that of theScorePlayer variable, I want it to add more elements in it (ScoreDealer) but I do not want the sum of the elements to exceed the value of21.

I used the Break method but the infinite loop continues and hangs the application.

The function that do this:

finishGame = () => {
  const scorePlayer = this.state.cardsPlayer.reduce((a, b) => a + b);

  const scoreDealer = this.state.cardsDealer.reduce((a, b) => a + b);

  for (let i = scoreDealer; scoreDealer < scorePlayer; i++) {

    this.setState({
      cardsDealer: this.state.cardsDealer.concat(this.state.cards.splice(0, 1))
    })

    if (scoreDealer === 21) {
      break;
    }
  }
}

Can anybody help me?

Upvotes: 0

Views: 127

Answers (1)

Joshua Fermin
Joshua Fermin

Reputation: 646

rossipedia state it perfect in this post.

don't call setState in a loop. What's happening here is exactly what the docs are referring to: this.state is returning the previous value, as the pending state update has not been applied yet.

Calling setState in a loop only updates state 1 time

The reason your app keeps on hanging is that this.state's values have not been updated yet and will not be updated till finishGame finishes executing, as well as some flawed logic as @Jayce444 stated in the comments above.

A solution I would use while keeping most of your logic is this

finishGame = () => {
    // this is a copy of your array given I'm assuming its a 1D array and you can now mutate it
    const cardsDealer = [...this.state.cardsDealer];
    // if you chose to update scorePlayer you should declare it as let.
    const scorePlayer = this.state.cardsPlayer.reduce((a, b) => a + b);
    let scoreDealer = this.state.cardsDealer.reduce((a, b) => a + b);

    for (let i = 0; scoreDealer < 21; i++) {
        scoreDealer += cardsDealer.shift();

        // this will stop if card is >= to 21
        if (scoreDealer >= 21) {
            break;
        }
    }
    // this will set your cards to the new values after the loop is done running.
    this.setState({cardsDealer});
}

given there is a lot of fine-tuning needed in the above function I hope it gets you off to a good start. Happy coding!

Upvotes: 1

Related Questions