反应 setState 并使用该值更新另一个状态

React setState and use the value to update another state

我有一个简单的掷骰子代码,我想根据掷骰子更新分数。

这是骰子的状态和分数:

 const [Dice1, setDice1] = useState(0);
 const [Dice2, setDice2] = useState(0);

 const [Score1, setScore1] = useState(0);
 const [Score2, setScore2] = useState(0);

 function randomNum() {
      setDice2(Math.floor(Math.random() * 6) + 1);
      setDice1(Math.floor(Math.random() * 6) + 1);
      Dice1 > Dice2 && Dice1 !== Dice2 ? setScore1(Score1 + 1) : Dice2 > Dice1 && Dice1 !== Dice2 ? setScore2(Score2 + 1) : setScore2(Score2 + 0);
 }

单击时触发函数 randomNum。

 return (
      <div className="App">
           <header className="App-header">
                <p>Player 1 rolls {Dice1}</p>
                <p>Player 2 rolls {Dice2}</p>
                <button onClick={randomNum}>Roll the dice</button>
                {Dice1 > Dice2 ? <p>Player 1 win</p> : Dice1 === Dice2 ? <p>Draw</p> : <p>Player 2 win</p>}
                <p>Player 1 score is {Score1} points</p>
                <p>Player 2 score is {Score2} points</p>
                <button onClick={resetScore}>Reset score</button>
           </header>
      </div>
 );

一切正常,除了分数更新有 1 轮滞后。 每次我滚动时,都会添加上一轮的点数。 我在这里做错了什么?

我能想到的最简单的方法是实现将两个状态都设置为 0 的 resetScore 函数。

function resetScore() { setScore1(0); setScore2(0); }

或在随机数的开头调用此函数。

您没有正确使用以前的状态值。更新状态变量时不建议直接使用之前的状态值。

所以在你的代码中而不是:

setScore1(Score1 + 1)

你应该这样做:

setScore1(prevScore => prevScore + 1);

其他状态变量也类似。

更新

一个分数状态看起来像

  const [score, setScore] = useState({
    score1: 0,
    score2: 0
  });

你可以更新

  setScore(prev=>{...prev, score1: prev.score1 + 1})
setScore(prev=>{...prev, score2: prev.score2 + 1})


试试这个

  1. 改为使用一种状态的骰子
const [dice, setDice] = useState({
    dice1: 0,
    dice2: 0,
  })

  1. 更新状态
function randomNum() {
    const dice1Val = Math.floor(Math.random() * 6) + 1;
    const dice2val = Math.floor(Math.random() * 6) + 1;
    setDice({
      dice1: dice1Val,
      dice2val: dice2Val
    })

  1. 并且由于设置分数是设置骰子的效果,因此在 useEffect
  2. 中更新分数
useEffect(() => {
      dice.dice1 > dice.dice2 && dice.dice1 !== dice.dice2 ? setScore1(prev => prev + 1); : dice.dice2 > dice.dice1 && dice.dice1 !== dice.dice2 ? setScore2(prev => prev + 1) : setScore2(prev => prev + 1)
    },[dice])
 }

您也可以将分数置于一种状态下。