javascript 计时器过期时的React

ivqmmu1c  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(174)

我目前正试图使一个API调用时,我的计时器击中零或在过去。
这是我的定时器组件

import { useState, useEffect } from "react";
import Box from "@mui/material/Box";
import { useDispatch } from "react-redux";
import { AppDispatch } from "../store";

const Timer = ({ deadline }: { deadline: Date }) => {
  const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(deadline));
  const [timerExpired, setTimerExpired] = useState(false);

  useEffect(() => {
    const intervalId = setInterval(() => {
      const remaining = getTimeRemaining(deadline);
      setTimeRemaining(remaining);

      if(remaining.days <= 0 && remaining.hours <= 0 && remaining.minutes <= 0 && remaining.seconds <= 0) {
        setTimerExpired(true);
        clearInterval(intervalId);

        const dispatch = useDispatch<AppDispatch>();
        try{
          console.log("TIMER EXPIRED");
        } catch (e){
          /* redux handles error */
        }
      }
    }, 1000);

    return () => clearInterval(intervalId);
  }, [deadline]);

  const { days, hours, minutes, seconds } = timeRemaining;

  return (
    <Box
    sx={{
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
      padding: "20px",
      fontSize: "35px",
      fontWeight: "bold"
    }}
  >
    {timerExpired ? (
      <p>Timer has expired.</p>
    ) : (
      <>
        {days === 1 ? (
          <p>
            {days} day {hours} hours {minutes} minutes {seconds} seconds
          </p>
        ) : (
          <p>
            {days} days {hours} hours {minutes} minutes {seconds} seconds
          </p>
        )}
      </>
    )}
  </Box>
      );
}

const getTimeRemaining = (deadline: Date) => {
  const total = deadline.getTime() - new Date().getTime();
  const days = Math.floor(total / (1000 * 60 * 60 * 24));
  const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
  const minutes = Math.floor((total / 1000 / 60) % 60);
  const seconds = Math.floor((total / 1000) % 60);

  return {
    days,
    hours,
    minutes,
    seconds
  };
};

export default Timer;

在这个组件中,我初始化计时器,它应该到期的时间:

const creationDate = new Date("2023-07-12");
    creationDate.setHours(9);
    creationDate.setMinutes(0);
    creationDate.setSeconds(0);

<Timer deadline={creationDate}/>

console.log("TIMER EXPIRED")永远不会被调用,即使我将createionDate设置为2023-01-01或过去的任何一天。
如果您需要更多的信息,请不要犹豫发表评论。
先谢谢你了。

pobjuy32

pobjuy321#

计时器只检查剩余时间是否为零,而不检查最后期限是否已过。如果剩余时间变为负值,则永远不满足将timerExpired设置为true的条件。

const Timer = ({ deadline }: { deadline: Date }) => {
  const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(deadline));
  const [timerExpired, setTimerExpired] = useState(false);

  useEffect(() => {
    if (deadline < new Date()) {
      setTimerExpired(true);
      const dispatch = useDispatch<AppDispatch>();
      try {
        console.log("TIMER EXPIRED");
      } catch (e) {
        /* redux handles error */
      }
    } else {
      const intervalId = setInterval(() => {
        const remaining = getTimeRemaining(deadline);
        setTimeRemaining(remaining);

        if (
          remaining.days <= 0 &&
          remaining.hours <= 0 &&
          remaining.minutes <= 0 &&
          remaining.seconds <= 0
        ) {
          setTimerExpired(true);
          clearInterval(intervalId);

          const dispatch = useDispatch<AppDispatch>();
          try {
            console.log("TIMER EXPIRED");
          } catch (e) {
            /* redux handles error */
          }
        }
      }, 1000);

      return () => clearInterval(intervalId);
    }
  }, [deadline]);

  const { days, hours, minutes, seconds } = timeRemaining;
};

const getTimeRemaining = (deadline: Date) => {
  const total = deadline.getTime() - new Date().getTime();
  const days = Math.floor(total / (1000 * 60 * 60 * 24));
  const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
  const minutes = Math.floor((total / 1000 / 60) % 60);
  const seconds = Math.floor((total / 1000) % 60);

  return {
    days,
    hours,
    minutes,
    seconds,
  };
};

export default Timer;
mfuanj7w

mfuanj7w2#

您可以将total添加到getTimeRemaining中的返回,然后检查。

if ( remaining.total <= 0 ) {

然后你的代码应该工作,我做了一个example stackblitz

相关问题