【问题标题】:React setState and use the value to update another state反应 setState 并使用该值更新另一个状态
【发布时间】:2022-01-16 08:10:02
【问题描述】:

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

这是骰子的状态和分数:

 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 轮滞后。 每次我滚动时,都会添加上一轮的分数。 我在这里做错了什么?

【问题讨论】:

    标签: reactjs use-state setstate


    【解决方案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中的分数
    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])
     }
    

    您也可以将分数放在一个状态下。

    【讨论】:

    • 谢谢!它起作用了,我将阅读有关 useEffect 和 prev => prev 函数的信息,因为此时,我不明白它是如何工作的。我也为分数设置了一个状态,但我不确定现在如何重写 useEffect,我尝试了这个,但它似乎不起作用 setScore({ score1: (prev) => prev + 1 })
    • @Chris 更新了我的答案
    【解决方案2】:

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

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

    或者在 randomNum 的开头调用这个函数。

    【讨论】:

    • 对不起,这与我的问题无关。
    【解决方案3】:

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

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

    setScore1(Score1 + 1)
    

    你应该这样做:

    setScore1(prevScore => prevScore + 1);
    

    对于其他状态变量也是如此。

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 2018-12-08
      • 2021-06-02
      • 2021-06-02
      • 2021-12-30
      相关资源
      最近更新 更多