Как остановить setInterval, определенный вне эффекта использования

#reactjs

#реагирует на

Вопрос:

Я хочу, чтобы индикатор выполнения увеличивал его значение каждые 5 секунд. Я использовал setInterval, который увеличивает значение состояния и пытается очистить значение состояния, как только значение состояния равно 100. Но это не очищает интервал, и значение состояния не изменяется должным образом.

 import {useState, useEffect} from 'react';  function App() {  const [percentage,setPercentage] = useState(99)   let progressInterval = setInterval(()=gt;{  console.log(percentage);  setPercentage(percentage 1);  },10000);   useEffect(() =gt; {  if(percentage === 100) {  console.log("completed");  clearInterval(progressInterval);  }  }, [percentage])   const progress = {  backgroundColor: 'yellow',  width: `${percentage}%`,  textAlign: 'right',  }  const fullWidth = {  border: '1px solid black',  backgroundColor: '#eff',  margin: '10px'  }   return (  lt;gt;  lt;div style={fullWidth}gt;  lt;div style={progress}gt;{percentage}%lt;/divgt;  lt;/divgt;  lt;/gt;  ); }  export default App;  

Ответ №1:

Когда вы измените состояние, ваш компонент будет повторно отправлен, а ваша progressInterval переменная будет повторно инициализирована.

вы должны инициализировать переменную интервала внутри функции обратного вызова:

 import {useState, useEffect, useCallback} from 'react';  let progressInterval = ''; function App() {  const [percentage,setPercentage] = useState(99);  const initInterval = useCallback(() =gt; {  progressInterval = setInterval(()=gt;{  console.log(percentage);  setPercentage(percentage 1);  },10000);  }, []);   useEffect(() =gt; {  if(percentage === 100) {  console.log("completed");  clearInterval(progressInterval);  }  }, [percentage])  const progress = {  backgroundColor: 'yellow',  width: `${percentage}%`,  textAlign: 'right',  }  const fullWidth = {  border: '1px solid black',  backgroundColor: '#eff',  margin: '10px'  }  return (  lt;gt;  lt;div style={fullWidth}gt;  lt;div style={progress}gt;{percentage}%lt;/divgt;  lt;/divgt;  lt;/gt;  ); }  

экспорт приложения по умолчанию;

Комментарии:

1. Это не увеличивает значение состояния на 1, значение увеличивается, как 1,6,23,76,237 и так далее, и так далее

Ответ №2:

Если progressInterval может быть переменная состояния, это может быть решением:

 function App() {  const [percentage, setPercentage] = useState(99);  const [progressInterval, setProgressInterval] = useState();   useEffect(() =gt; {  let progressInterval = setInterval(() =gt; {  console.log(percentage);  setPercentage((prev) =gt; prev   1);  }, 10000);   setProgressInterval(progressInterval);   // Optional but a recommendation  // Clearing the interval if component unmounts before reaching 100 percent  return () =gt; clearInterval(progressInterval);   }, []);   useEffect(() =gt; {  if (percentage === 100) {  console.log("completed");  clearInterval(progressInterval);  }  }, [percentage]);  ... rest of the code  }  

Ответ №3:

Вы можете установить функцию возврата для вашего эффекта использования следующим образом

 useEffect(() =gt; {  const timer = setTimeout(() =gt; {    if(progress lt; 0.9){  setProgress(progress   0.2);  }  else{  retrieveData();  }    }, 1000);  return () =gt; {  clearTimeout(timer);  };  }, [progress]);