#reactjs #use-effect
#reactjs #использование-эффект
Вопрос:
Я пытаюсь использовать перехват useEffect как способ создания асинхронного таймера в react. Логика находится внутри timeFunc(), и useEffect работает так, что вызывает функцию каждые 1000 мс. Странная часть заключается в том, что по какой-то причине, когда timeFunc() вызывается (каждую секунду), он обращается только к старым значениям переменных (в частности, «приостановлено»). Например, если интервал начинается со значения «приостановлено», равного false, даже если я изменю значение «приостановлено» на true (приостановлено — это переменная состояния, переданная родительским компонентом), timeFunc() все равно будет считать, что приостановлено равно false . Не могу понять. Любая помощь приветствуется!
Код:
//TIMER MANAGER
let timeFunc = () => {
if(paused == false){
let delta = Math.trunc((new Date() - resumedTime)/1000);
setProgress(delta);
console.log('test ' paused);
} else {
clearInterval(interval);
}
}
useEffect(() => {
let interval = null;
interval = setInterval(() => {
timeFunc();
}, 1000);
return () => clearInterval(interval);
}, [initialized]);
Ответ №1:
timeFunc
Зависит от наличия актуального значения paused
, но оно не существует в useEffect
массиве зависимостей.
Либо добавьте его в массив зависимостей, а также сохраните время до следующего интервала в состоянии, либо используйте ссылку paused
вместо (со стабильной ссылкой) (или в дополнение к состоянию), например:
const pausedRef = useRef(false);
// ...
const timeFunc = () => {
if (!pausedRef.current) {
// ...
// to change it:
pausedRef.current = !pausedRef.current;
Также обратите внимание, что
let interval = null;
interval = setInterval(() => {
timeFunc();
}, 1000);
упрощает
const interval = setInterval(timeFunc, 1000);