反应 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})
试试这个
- 改为使用一种状态的骰子
const [dice, setDice] = useState({
dice1: 0,
dice2: 0,
})
- 更新状态
function randomNum() {
const dice1Val = Math.floor(Math.random() * 6) + 1;
const dice2val = Math.floor(Math.random() * 6) + 1;
setDice({
dice1: dice1Val,
dice2val: dice2Val
})
- 并且由于设置分数是设置骰子的效果,因此在
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])
}
您也可以将分数置于一种状态下。
我有一个简单的掷骰子代码,我想根据掷骰子更新分数。
这是骰子的状态和分数:
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})
试试这个
- 改为使用一种状态的骰子
const [dice, setDice] = useState({
dice1: 0,
dice2: 0,
})
- 更新状态
function randomNum() {
const dice1Val = Math.floor(Math.random() * 6) + 1;
const dice2val = Math.floor(Math.random() * 6) + 1;
setDice({
dice1: dice1Val,
dice2val: dice2Val
})
- 并且由于设置分数是设置骰子的效果,因此在
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])
}
您也可以将分数置于一种状态下。