在API调用后用钩子更新状态后,我试图用倒数计时运行一个函数,但由于状态尚未更新,我遇到了麻烦。将useEffect
与setInterval
一起使用也不起作用,因为它会创建许多设置间隔的实例,这些实例会使一切停滞。
async function fetchData() {
const res = await fetch(API);
res.json()
.then(res => {
setTime(res);
})
.catch(err => console.log(err))
}
const setTime = (data) => {
const obj = Time(data);
setDays(obj.day)
setHours(obj.hour)
setMinutes(obj.minute);
setSeconds(obj.second);
useEffect(() => {
fetchData();
}, []);
useEffect(() => {
runClock();
}, [seconds]) //I understand why it happens since it will run useEffect every time seconds changes
function runClock() {
let intervalId = setInterval(() => {
console.log(seconds+ "seconds")
if(seconds > 0){
setSeconds(prevSeconds => prevSeconds -1);
}
// more logic...
}
我不确定我想做的事情是否可行或者我是否需要另一种方法?作为参考,我在做一个倒数计时器。
答案 0 :(得分:0)
您可以使用setInterval并将runClock()
函数内部的所有逻辑带到具有秒依赖性的useEffect。然后,将时间间隔ID收集到变量中,然后执行清除功能以消除超时。这样,当下一个效果运行时,它将设置一个新的效果。这样,您就不会遇到太多setInterval实例
为此,您应该从效果中返回一个清除间隔的函数。
useEffect(() => {
let intervalId = setInterval(() => {
console.log(seconds+ "seconds")
if(seconds > 0){
setSeconds(prevSeconds => prevSeconds -1);
}
// more logic...
}
return clearInterval(intervalId)
}, [seconds])
有关useEffects here的更多信息