我想每秒增加状态[second] = [second + 1]。
const [second,setSecond] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSecond(second+1)
}, 1000);
return () => clearInterval(interval);
}, []);
但是似乎发生了无限循环,[second]仅增加了一次,从0到1,并且停止运行。
我从更改了代码
setSecond(second+1)
到
setSecond((second) => {return second+1})
并且这个运行没有问题:
const [second,setSecond] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSecond((second) => {return second+1})
}, 1000);
return () => clearInterval(interval);
}, []);
严重的是,我仍然不清楚。有人可以向我解释为什么吗?预先感谢!
答案 0 :(得分:2)
查看您的代码,我认为问题在于秒值绑定为0。
const [second,setSecond] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSecond(second+1)
}, 1000);
return () => clearInterval(interval);
}, []);
在安装组件时,将执行useEffect。那时您正在创建一个函数并将其传递给setInterval。该函数将在创建时使用second
的值(等于0)。因此,每次运行setInterval时,它都会执行setSecond(0+1)
,该值始终等于1。
您提到的正确方法有效,因为您为它提供了一个函数,该函数每次执行时都会将状态的当前值传递给它。
答案 1 :(得分:1)
Ciao,您用来设置second
的2种方法是不同的。
这种方式:
setSecond(second+1)
不考虑second
的上一个值。它只是尝试通过读取second
的当前值将秒增加1。考虑到setSecond
是异步的,因此不能保证下一个setInterval
会被前一个second
更新。这样,您就可以产生故障。
这种方式:
setSecond
是正确的。在这里,您正在考虑setSecond((second) => {return second+1})
的上一个值(通过使用箭头功能)。因此,在这种情况下,second
将正确更新。
您可以进行测试:按下一个按钮,然后在onclick函数上尝试编写:
second
您会看到setSecond(second+1)
setSecond(second+1)
将增加1(而不是预期的2)。
现在像这样修改您的代码:
second
您会看到setSecond((second) => {return second+1})
setSecond((second) => {return second+1})
将增加2!
发生这种情况是因为钩子是异步的。