用钩子设置状态后运行功能

时间:2020-01-14 19:44:51

标签: javascript reactjs react-hooks use-effect

在API调用后用钩子更新状态后,我试图用倒数计时运行一个函数,但由于状态尚未更新,我遇到了麻烦。将useEffectsetInterval一起使用也不起作用,因为它会创建许多设置间隔的实例,这些实例会使一切停滞。

 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...
}

我不确定我想做的事情是否可行或者我是否需要另一种方法?作为参考,我在做一个倒数计时器。

1 个答案:

答案 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的更多信息