【发布时间】:2022-10-13 19:27:17
【问题描述】:
我在这里有点困惑,如果有人能解释为什么useState 表现出这种行为,我将不胜感激。我有一个使用 useState 的功能组件,它启动一个计时器并在 DOM 中实时正确地呈现时间。停止计时器后,我想将时间推送到一个数组,但每次尝试都只是推送 0 - time 变量的初始状态。
经过一些调试后,我注意到如果我 console.log() 间隔循环函数内的时间它也会继续记录 0,而不是“真实”时间。
这是我的代码。我已经删除了与手头问题无关的所有部分。
export default function Timer() {
const [time, setTime] = useState(0);
const interval = useRef(null);
clearInterval(interval.current);
let startTime = Date.now() - time;
interval.current = setInterval(() => {
setTime(Date.now() - startTime);
console.log(time); // <-- Why does this continue to show 0?
}, 10);
return (
<div>
<span>{("0" + Math.floor((time / 60000) % 1000)).slice(-2)}:</span>
<span>{("0" + Math.floor((time / 1000) % 1000)).slice(-2)}.</span>
<span>{("00" + (time % 1000)).slice(-3, -1)}</span>
</div>
);
}
所以我的问题是,为什么time 变量返回正确的时间实时在 DOM 内部但不在控制台中?我认为这可能是因为 useState 不是即时的,但我不明白为什么它会继续记录 0。
编辑:
我通过声明一个单独的变量curTime = 0 解决了这个问题,而不是使用setTime(Date.now() - startTime),而是使用curTime = (Date.now() - startTime):
export default function Timer() {
const [time, setTime] = useState(0);
const interval = useRef(null);
let curTime = 0
clearInterval(interval.current);
let startTime = Date.now() - time;
interval.current = setInterval(() => {
curTime = (Date.now() - startTime);
setTime(curTime)
console.log(curTime); // <-- Now shows correct time.
}, 10);
return (
<div>
<span>{("0" + Math.floor((time / 60000) % 1000)).slice(-2)}:</span>
<span>{("0" + Math.floor((time / 1000) % 1000)).slice(-2)}.</span>
<span>{("00" + (time % 1000)).slice(-3, -1)}</span>
</div>
);
}
【问题讨论】:
-
区间函数中的
time总是与最初设置的变量相同,因为区间函数是一个闭包。如果您想要最新的,则需要通过useEffect访问它 -
如果我包含的整个代码部分都包含在它自己的函数中,这仍然有效吗?
标签: javascript reactjs react-hooks