Reputation: 1
I am in the process of building a React app and I want to be able to set the state of upperScoreBonus as soon as all of the other scores are not undefined. If the total of the all the scores are greater than 63, then add the bonus, otherwise only score 0.
Where I'm stuck is the applyUpperScoreBonus function is delayed until the next time that the roll function is called. I'm at a loss on where I should make this call to applyUpperScoreBonus.
I know I'm missing something.
class Game extends Component {
constructor(props) {
super(props);
this.state = {
dice: Array.from({ length: NUM_DICE }),
locked: Array(NUM_DICE).fill(false),
rollsLeft: NUM_ROLLS,
isRolling: false,
scores: {
ones: undefined,
twos: undefined,
threes: undefined,
fours: undefined,
fives: undefined,
sixes: undefined,
upperBonusScore: undefined
}
};
this.roll = this.roll.bind(this);
this.doScore = this.doScore.bind(this);
this.applyUpperScoreBonus = this.applyUpperScoreBonus.bind(this);
}
doScore(rulename, ruleFn) {
// evaluate this ruleFn with the dice and score this rulename
// only allows an update to the score card if the vaule has not yet been set.
if (this.state.scores[rulename] === undefined) {
this.setState(st => ({
scores: { ...st.scores, [rulename]: ruleFn(this.state.dice)},
rollsLeft: NUM_ROLLS,
locked: Array(NUM_DICE).fill(false)
}));
this.applyUpperScoreBonus();
this.roll();
}
}
applyUpperScoreBonus() {
const st = this.state.scores;
const upperArrayScores = [st.ones, st.twos, st.threes, st.fours, st.fives, st.sixes];
let totalUpperScore = 0;
upperArrayScores.forEach(idx => {
if(idx !== undefined) {
totalUpperScore += idx
}
})
if(upperArrayScores.every(idx => idx !== undefined)) {
//if the total is more than 63, apply bonus of 35 otherwise 0
this.setState(st => ({
scores: { ...st.scores, upperBonusScore: totalUpperScore >= 63 ? 35 : 0},
}));
}
}
Upvotes: 0
Views: 67
Reputation: 6130
Here this.applyUpperScoreBonus()
is called after the setState
, since the setState({})
is async, this.applyUpperScoreBonus()
only get state update on next doScore()
call
This is your code block
if (this.state.scores[rulename] === undefined) {
this.setState(st => ({
scores: { ...st.scores, [rulename]: ruleFn(this.state.dice)},
rollsLeft: NUM_ROLLS,
locked: Array(NUM_DICE).fill(false)
}));
this.applyUpperScoreBonus();
this.roll();
}
Change it to
if (this.state.scores[rulename] === undefined) {
this.setState(st => ({
scores: { ...st.scores, [rulename]: ruleFn(this.state.dice)},
rollsLeft: NUM_ROLLS,
locked: Array(NUM_DICE).fill(false)
}),()=> this.applyUpperScoreBonus()); // update here
this.roll();
}
Here, this.applyUpperScoreBonus()
is called on setState()
callback, so the function will get the updated state value.
Upvotes: 1