按下按钮启动 setInterval() 后,如何在满足条件后清除间隔

After a button is pressed to start a setInterval(), how do I clearInterval once a condition is met

我有一个应用程序可以在按下按钮时启动一个间隔。 我想在状态达到 5 后停止间隔。 我试过在 UseEffect 中添加 if 条件,并尝试将条件放在函数本身中,但两者似乎都不起作用。 console.log(sequence) 确实在 useEffect 中成功打印我可以看到序列确实增加了,但它一直增加到超过 5,并且从不增加 clearInterval

  const [sequence, setSequence] = useState(0)
    
    const interval = () =>{
        setInterval(() => {
            setSequence((prevSequence) => (
                prevSequence+1
            ))
        }, 2000);
    }

    const plant = ()=>{
        interval()
        console.log(sequence)
        if(sequence>5){
           clearInterval (interval)
        }
    }

    useEffect(() => {
        console.log(sequence)
        if(sequence>5){
            return () => clearInterval(interval);
        }
      }, [sequence]);

 return(
    <View style = {styles.container} >
        <Image
            style={{height:500,width:300,}}
            source= {tomato[sequence]}
        />
        <Button 
        title = 'Fertilize Plant' 
        style= {styles.text}
        onPress= {plant}>
        </Button>

    </View>)
}

您可以使用 clearInterval 功能来停止您设置的间隔。

这是一个例子;

let counter = 0;

const interval = setInterval(() => {
  counter++;

  console.log(`Counter = ${counter}`);

  if (counter >= 3) {
    console.log("Interval Stopped");
    clearInterval(interval);
  }
}, 1000);

问题

您没有正确清除间隔。

const interval = () => {
  setInterval(() => {
    setSequence((prevSequence) =>  prevSequence + 1)
  }, 2000);
};

...

useEffect(() => {
  console.log(sequence);
  if (sequence > 5) {
    return () => clearInterval(interval);
  }
}, [sequence]);

这里interval是对函数的引用,不是从[=16=返回的实际间隔计时器id ].

解决方案

将间隔计时器 ID 存储在要在组件周围引用的 React ref 中。

const intervalRef = useRef();

const interval = () => {
  intervalRef.current = setInterval(() => {
    setSequence((prevSequence) =>  prevSequence + 1)
  }, 2000);
};

...

useEffect(() => {
  const intervalId = intervalRef.current;

  // also clear on component unmount
  return () => clearInterval(intervalId);
}, []);

useEffect(() => {
  if (sequence > 5) {
    clearInterval(intervalRef.current);
  }
}, [sequence]);

此外,不需要检查 sequence 值并清除 plant 回调中的间隔,依赖于 sequenceuseEffect 挂钩将处理该问题. Plant只需要开始间隔

const plant = () => {
  interval();
};