不同函数中状态变量的值不同 [英] Value of a state variable different in a different function
本文介绍了不同函数中状态变量的值不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我搞不懂作用域在Reaction中的工作原理。
我想将一个状态的值传递给另一个状态,但我发现在一个函数中它打印了正确的值,而在另一个函数中却没有。
这是一个倒计时,计时器倒计时并计算点击量,最后,我想要获得总点击量并将其发送到总状态。因此,状态为:
const [strokeScore, setStrokeScore] = useState(1);
const [totalStrokeScore, setTotalStrokeScore] = useState(1);
const [strokeCountdown, setStrokeCountdown] = useState();
strokeScore
是游戏中的点击量--我想得到总点击数,并将其计入总击球分数。
由于某种原因,我无法执行此操作-这是怎么回事?
import React, { useEffect, useState } from 'react';
function ScoreCard() {
const [strokeScore, setStrokeScore] = useState(1);
const [totalStrokeScore, setTotalStrokeScore] = useState(1);
const [strokeCountdown, setStrokeCountdown] = useState();
const strokeCountdownDing = new Audio('/sounds/round-complete.mp3');
const endOfGameRound = () => {
strokeCountdownDing.play();
document.getElementById('stroke-counter-button').disabled = true;
}
const addToStrokeScore = () => {
setStrokeScore(strokeScore + 1);
// prints the correct number
console.log(strokeScore)
if (strokeCountdown === 0) {
endOfGameRound()
}
}
const subtractStrokeScore = () => {
setStrokeScore(strokeScore - 1);
}
const countDown = () => {
// let strokeCountdown = Math.floor(Math.random() * 31) + 100;
let strokeCountdown = 10
let strokeCountdownSpeedOptions = [1000, 500, 300, 200];
let strokeCountDownSpeed = strokeCountdownSpeedOptions[Math.floor(Math.random()*strokeCountdownSpeedOptions.length)];
let strokeCounter = setInterval(() => {
strokeCountdown--
// this is always giving me...1...?
console.log('the score is: ' + strokeScore)
setStrokeCountdown(strokeCountdown)
if (strokeCountdown === 0) {
endOfGameRound()
clearInterval(strokeCounter)
setTotalStrokeScore(strokeScore);
}
}, strokeCountDownSpeed)
}
useEffect(() => {
countDown();
}, []);
return (
<div className="gane__score-card">
<div className="gane__speed-level">
Speed: idk
</div>
<div className="gane__stroke-countdown">
Countdown: {strokeCountdown}
</div>
<p>Score: {strokeScore}</p>
<button id="stroke-counter-button" onClick={addToStrokeScore}>
{strokeCountdown === 0 ? 'Game Over' : 'Stroke'}
</button>
{/* window.location just temp for now */}
{strokeCountdown === 0
? <button onClick={() => window.location.reload(false)}>Play Again</button>
: <button disabled>Game in Progress</button>
}
<div className="gane__total-score">
Total score: {totalStrokeScore}
</div>
</div>
);
}
export default ScoreCard;
如果您看上面的示例,我会评论它给出正确数字的地方以及它似乎停滞在&q;1&q;的地方-为什么会这样?
我也尝试将其作为其他变量。
import React, { useEffect, useState } from 'react';
function ScoreCard() {
const [strokeScore, setStrokeScore] = useState(1);
const [totalStrokeScore, setTotalStrokeScore] = useState(1);
const [strokeCountdown, setStrokeCountdown] = useState();
const strokeCountdownDing = new Audio('/sounds/round-complete.mp3');
// make new variable, maybe?
let strokeScoreCount = 0;
const endOfGameRound = () => {
strokeCountdownDing.play();
document.getElementById('stroke-counter-button').disabled = true;
}
const addToStrokeScore = () => {
setStrokeScore(strokeScore + 1);
// prints the correct number
console.log(strokeScore)
// but this just gives me zero?
strokeScoreCount = strokeScoreCount + 1;
console.log('maybe do a different var? : ' + strokeScoreCount)
if (strokeCountdown === 0) {
endOfGameRound()
}
}
const subtractStrokeScore = () => {
setStrokeScore(strokeScore - 1);
}
const countDown = () => {
// let strokeCountdown = Math.floor(Math.random() * 31) + 100;
let strokeCountdown = 10
let strokeCountdownSpeedOptions = [1000, 500, 300, 200];
let strokeCountDownSpeed = strokeCountdownSpeedOptions[Math.floor(Math.random()*strokeCountdownSpeedOptions.length)];
let strokeCounter = setInterval(() => {
strokeCountdown--
// this is always giving me...1...?
console.log('the score is: ' + strokeScore)
// this just gives me zero all the time? why?
console.log('the new variable to use is: ' + strokeScoreCount)
setStrokeCountdown(strokeCountdown)
if (strokeCountdown === 0) {
endOfGameRound()
clearInterval(strokeCounter)
setTotalStrokeScore(strokeScore);
}
}, strokeCountDownSpeed)
}
useEffect(() => {
countDown();
}, []);
return (
<div className="game__score-card">
<div className="game__speed-level">
Speed: idk
</div>
<div className="game__stroke-countdown">
Countdown: {strokeCountdown}
</div>
<p>Score: {strokeScore}</p>
<button id="stroke-counter-button" onClick={addToStrokeScore}>
{strokeCountdown === 0 ? 'Game Over' : 'Stroke'}
</button>
{/* window.location just temp for now */}
{strokeCountdown === 0
? <button onClick={() => window.location.reload(false)}>Play Again</button>
: <button disabled>Game in Progress</button>
}
<div className="game__total-score">
Total score: {totalStrokeScore}
</div>
</div>
);
}
export default ScoreCard;
使用新变量只会使我始终为零,而strokeScore在该函数中仅永久停留在1。但这是一个州,你在任何地方都不能得到州吗?
如何从一个状态获取值,确保它在所有作用域中都正确,并将其传递到另一个状态?
注意:下面的答案解释了状态和范围,但代码破坏了setInterval。问题来了:useState with an argument in it's array is breaking a setInterval and makes it glitchy and erratic
推荐答案
如果执行setState(somevalue); console.log(state)
,state
将显示旧值而不是新值,因为它尚未更新。
如果执行以下操作,strokeScore
将反映旧值,因为它尚未更新。
setStrokeScore(strokeScore + 1);
console.log(strokeScore)
您可以在useEffect调用中看到更新后的分数。试着做以下事情,你就知道我在说什么了。
useEffect(() => {
console.log('Score in useeffect', strokeScore);
}, [strokeScore])
const addToStrokeScore = () => {
setStrokeScore(strokeScore + 1);
console.log('Score in function', strokeScore);
}
此外,如果新值依赖于旧值,则设置状态的正确方法是
setStrokeScore( prev => prev + 1);
因此最终代码应类似于以下
useEffect(() => {
console.log('Score in useeffect', strokeScore); //shows new value
}, [strokeScore])
const addToStrokeScore = () => {
setStrokeScore(prev => prev + 1);
console.log('Score in function', strokeScore); //shows old value
}
甚至更好,让事情更上一层楼。
const addToStrokeScore = () => {
const newScore = strokeScore + 1;
// do whatever you need with the new score, then update state when done.
setStrokeScore(newScore);
console.log('Score in function', newScore);
}
这篇关于不同函数中状态变量的值不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文