React Hooks Clock - 在特定时间后清除 SetInterval

React Hooks Clock - Clear SetInterval After Certain Time

我在 React 中有一个秒表功能,我想在 15 分钟后停止。我不确定在这种情况下如何使用 clearInterval()

  const [timer, setTimer] = useState(0);
  const [isActive, setIsActive] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const countRef = useRef(null);
  const lastUpdatedRef = useRef(null);
  const [minutes,setMinutes] = useState(0)
  const [seconds,setSeconds] = useState(0)


  const timeCeiling = 900; //maximum minutes is 15
  const timeFloor = 60; //maximum seconds is 60 so it resets after

  useEffect(() => {
    if (timer < timeCeiling) {
      setMinutes(Math.floor(timer / 60));
      setSeconds(timer % 60);
    } else {
      setMinutes(15);
      setSeconds(0);
    }
  }, [timer]);


  const handleStart = () => {
    setIsActive(true);
    setIsPaused(true);
    countRef.current = setInterval(() => {
      setTimer((timer) => timer + 1);
    }, 1000);
    lastUpdatedRef.current = setInterval(() => {
      setLastUpdated(Date.now());
    }, 30000);
  };

用户点击触发 useEffecthandleStart 函数。它还有一个 lastUpdated 依赖项,每 30 秒触发另一个函数。

时钟应该在 15:00 之后结束,但它仍然会在之后继续 - 我应该把 clearInterval 放在哪里,以便它在 15 分钟后停止时钟?或者还有其他方法吗?

每次 timer 更新时,我都会将它放在 useEffect 中,即 运行。达到限制时清除else分支中的间隔。

useEffect(() => {
  if (timer < timeCeiling) {
    setMinutes(Math.floor(timer / 60));
    setSeconds(timer % 60);
  } else {
    clearInterval(countRef.current);
    setMinutes(15);
    setSeconds(0);
  }
}, [timer]);

您可能还想添加一个额外的 useEffect 挂钩,以在组件卸载之前清除所有 运行 计时器,然后再手动清除它们。

useEffect(() => {
  return () => {
    clearInterval(countRef.current);
    clearInterval(lastUpdatedRef.current);
  };
}, []);

我认为你应该在 useEffect 的 else 块中使用 clearInterval。也许这样:

else {
  setMinutes(15);
  setSeconds(0);
  clearInterval(countRef.current) // I hope this works
}

您可以在else条件中加入清除间隔:

useEffect(() => {
  if (timer < timeCeiling) {
    setMinutes(Math.floor(timer / 60));
    setSeconds(timer % 60);
  } else {
    setMinutes(15);
    setSeconds(0);
    countRef.current && clearInterval(countRef.current);
    lastUpdatedRef.current && clearInterval(lastUpdatedRef.current);
  }
}, [timer]);

并且您应该在卸载组件时清除间隔:

useEffect(() => {
  return () => {
    countRef.current && clearInterval(countRef.current);
  };
}, [countRef]);

useEffect(() => {
  return () => {
    lastUpdatedRef.current && clearInterval(lastUpdatedRef.current);
  };
}, [lastUpdatedRef]);