Что происходит: у меня есть эти две переменные: ScorePlayer и ScoreDealer, которые являются результатом суммы элементов, содержащихся в основном массиве каждой из них cardsPlayer и cardsDealer.
И я хочу провести проверку. Если значение переменной ScoreDealer меньше, чем значение переменной ScorePlayer, я хочу, чтобы она добавила в нее больше элементов (ScoreDealer), но я не хочу, чтобы сумма элементов превышала значение 21.
Я использовал метод Break, но бесконечный цикл продолжается и приложение зависает.
Функция, которая делает это:
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;
}
}
}
Кто-нибудь может мне помочь?
Кроме того, splice() напрямую изменяет массив, который его вызывает, поэтому ваш код this.state.cards.splice(0, 1) будет напрямую изменять состояние, и это большой недостаток. Непосредственно изменяющееся состояние вызывает проблемы и непредсказуемое поведение.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


rossipedia заявляет, что это идеально в этом посте.
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.
Вызов setState в цикле обновляет состояние только 1 раз
Причина, по которой ваше приложение продолжает зависать, заключается в том, что значения this.state еще не обновлены и не будут обновлены до тех пор, пока finishGame не завершит выполнение, а также некоторая некорректная логика, как указано в комментариях @ Jayce444 выше.
Решение, которое я бы использовал, сохраняя большую часть вашей логики, это
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});
}
учитывая, что в приведенной выше функции требуется много тонкой настройки, я надеюсь, что это даст вам хорошее начало. Удачного кодирования!
Привет, Джошуа, большое спасибо за твой ответ, но выдал эту ошибку: Syntax error: C:/Users/IBM_ADMIN/Desktop/blackjack/blackjack/src/App.js: "scoreDealer" is read-only, ты знаешь почему?
woops, я обновил свой ответ, потому что scoreDealer был установлен как const.
Ваша логика кажется не совсем правильной. Вы устанавливаете
scoreDealerвне цикла, поэтому он никогда не изменится внутри цикла (таким образом, условие никогда не будет выполнено). Кроме того, похоже, что вы относитесь кsetState()как к синхронному, но это не так.setState()асинхронный. Вы не можете предположить, что состояние изменилось сразу после его вызова.