从状态更改反应状态的最佳方法是什么?

时间:2020-01-29 12:07:53

标签: reactjs state

我正在构建一个React应用,我希望能够在所有其他分数都未定义时立即设置upperScoreBonus的状态。如果所有分数的总和大于63,则添加奖金,否则仅分数0。

我被卡住的地方是applyUpperScoreBonus函数被延迟到下一次调用roll函数。我不知道应该在哪里调用applyUpperScoreBonus。

我知道我想念一些东西。

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},
      }));

      } 

  }

1 个答案:

答案 0 :(得分:1)

this.applyUpperScoreBonus()之后调用setState,因为setState({})是异步的,this.applyUpperScoreBonus()仅在下一次doScore()调用时获得状态更新

这是您的代码块

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();

    }

将其更改为

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();

        }

在这里,this.applyUpperScoreBonus()setState()回调中被调用,因此该函数将获取更新后的状态值。