首页 > 解决方案 > setTimeout() 函数未检测到状态变化并继续执行递归函数

问题描述

useEffect(() => {
  playLoop();
}, [state.playStatus]);

const playLoop = () => {
  if (state.playStatus) {
    setTimeout(() => {
      console.log("Playing");
      playLoop();
    }, 2000);
  } else {
    console.log("Stopped");
    return;
  }
};

Output: 
Stopped
// State Changed to true
Playing
Playing
Playing
Playing
// State Changed to false
Stopped
Playing // This is the problem, even the state is false this still goes on execute the Truthy stalemate
Playing
Playing

我正在研究 react-native,我希望在状态值变为 false 时停止递归。有没有其他方法可以实现这个代码我只想在状态值为真时重复执行一个函数。谢谢

标签: javascriptreactjsreact-native

解决方案


而不是一个playStatus布尔值,我会保存间隔ID。这样,而不是设置playStatusfalse,调用clearInterval。同样,不要设置playStatus为,而是true调用setInterval

// Can't easily use useState here, because you want
// to be able to call clearInterval on the current interval's ID on unmount
// (and not on re-render) (interval ID can't be in an old state closure)
const intervalIdRef = useRef(-1);
const startLoop = () => {
  // make sure this is not called while the prior interval is running
  // or first call clearInterval(intervalIdRef.current)
  intervalIdRef.current = setInterval(
    () => { console.log('Playing'); },
    2000
  );
};
const stopLoop = () => {
  clearInterval(intervalIdRef.current);
};
// When component unmounts, clean up the interval:
useEffect(() => stopLoop, []);

推荐阅读