【问题标题】:React Hooks Clock - Clear SetInterval After Certain TimeReact Hooks Clock - 在一定时间后清除 SetInterval
【发布时间】:2021-10-27 02:04:08
【问题描述】:

我在 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 分钟后停止时钟?还是有其他方法可以做到这一点?

【问题讨论】:

    标签: javascript reactjs react-hooks setinterval


    【解决方案1】:

    可以在 else 条件下添加 cleare 间隔:

    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]);
    

    【讨论】:

      【解决方案2】:

      我会将它放在每次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);
        };
      }, []);
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-05
          • 1970-01-01
          • 2020-07-15
          • 2017-12-07
          • 2019-06-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多