Запустить функцию после установки состояния с помощью крючков - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь запустить функцию с обратным отсчетом после обновления состояния с помощью ловушек после вызова 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...
}

Я не уверен, возможно ли то, что я пытаюсь сделать, или мне просто нужен другой подход? И для справки, я делаю таймер обратного отсчета.

1 Ответ

0 голосов
/ 14 января 2020

Вы можете использовать setInterval и перенести все логи c внутри функции runClock() в useEffect, которое зависит от секунд. Затем вы собираете идентификатор интервала в переменную, а затем после этого реализуете функцию очистки, чтобы покончить с таймаутом. таким образом, когда следующий эффект будет запущен, он установит новый. таким образом, вы не столкнетесь с слишком большим количеством экземпляров setInterval

, для этого вы должны вернуть функцию из вашего эффекта, которая очищает интервал.


useEffect(() => {
     let intervalId = setInterval(() => {
        console.log(seconds+ "seconds")
       if(seconds > 0){
            setSeconds(prevSeconds => prevSeconds -1);
       }
// more logic...
      }
    return clearInterval(intervalId)
}, [seconds]) 

Подробнее о useEffects здесь

...