Как я могу добавить таймер обратного отсчета в свое приложение ReactJS

#javascript #node.js #reactjs #react-native

Вопрос:

Я новичок в ReactJS и пытаюсь реализовать таймер обратного отсчета, но в моем текущем коде мне нужно обновить страницу, чтобы показать фактический обратный отсчет. Здесь у меня есть два времени (1). Будущее время и (2). Текущее время и мне нужно показать другой статус, основанный на различии этих дат и времени. (а). если дата в будущем и дата сегодня совпадают, мой статус будет СЕГОДНЯ (b). если до будущей даты осталось 1 час, мне нужно показать таймер обратного отсчета с 59:59 (c). как только таймер обратного отсчета закончится, мой статус будет в режиме реального времени

Любая помощь будет оценена по достоинству. Заранее спасибо..

 import React, { useEffect, useRef, useState } from "react";
import moment from "moment";

let sDate = "2021-04-26T18:46:00.000Z";
let formatted_sDate = moment(sDate).utc().format("MM/DD/YYYY HH:mm:ss");
let eDate = moment(new Date()).format("MM/DD/YYYY HH:mm:ss");
const ONE_HOUR = 3600;

// compare two dates amp; get diff in days
function getDateDifferenceInDays(s, e) {
  const sDate = moment(s);
  const eDate = moment(e);
  const days = sDate.diff(eDate, "days");
  return days;
}

// compare two dates amp; get diff in seconds
function getTimeDifferenceInSeconds(s, e) {
  const sDate = moment(s);
  const eDate = moment(e);
  const seconds = sDate.diff(eDate, "seconds");
  return seconds;
}

function format(time) {
  // Hours, minutes and seconds
  var hrs = ~~(time / 3600);
  var mins = ~~((time % 3600) / 60);
  var secs = ~~time % 60;

  // Output like "1:01" or "4:03:59" or "123:03:59"
  var ret = "";
  if (hrs > 0) {
    ret  = ""   hrs   ":"   (mins < 10 ? "0" : "");
  }
  ret  = ""   mins   ":"   (secs < 10 ? "0" : "");
  ret  = ""   secs;
  return ret;
}

export default function App() {
  const timerBeforeCountDown = useRef();
  const currentTimer = useRef();
  const [time, setTime] = useState(null);
  const [startCurrentTimer, setStartCurrentTimer] = useState(false);

  useEffect(() => {
    const diffInDays = getDateDifferenceInDays(formatted_sDate, eDate);
    const diffInSeconds = getTimeDifferenceInSeconds(formatted_sDate, eDate);

    if (diffInDays === 0) {
      if (diffInSeconds > ONE_HOUR) {
        setTime(diffInSeconds);
        setStartCurrentTimer(false);
        timerBeforeCountDown.current = setInterval(() => {
          setTime((prev) => {
            if (prev > ONE_HOUR) {
              return prev - 1;
            } else {
              setStartCurrentTimer(true);
              clearInterval(timerBeforeCountDown.current);
            }
          });
        }, 1000);
      } else if (diffInSeconds <= ONE_HOUR amp;amp; diffInSeconds > 0) {
        setTime(diffInSeconds);
        setStartCurrentTimer(true);

        currentTimer.current = setInterval(() => {
          if (time > 0) {
            setTime((prev) => {
              if (prev > 0) {
                return prev - 1;
              } else {
                return prev;
              }
            });
          } else {
            clearInterval(currentTimer.current);
          }
        }, 1000);
      } else {
        return null;
      }
    } else {
      return null;
    }

    // clear intervel
    return () => {
      clearInterval(timerBeforeCountDown.current);
      clearInterval(currentTimer.current);
    };
  }, [startCurrentTimer]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>{time !== null amp;amp; time > ONE_HOUR amp;amp; "TODAY"}</h2>
      <h2>{time !== null amp;amp; time <= ONE_HOUR amp;amp; time > 0 amp;amp; format(time)}</h2>
      <h2>{time === 0 amp;amp; "LIVE"}</h2>
    </div>
  );
}
 

Комментарии:

1. Вам нужно добавить time в массив зависимостей крючка useEffect вместо параметра startCurrentTimer. Государству необходимо обновлять каждый time раз, когда оно обновляется.

Ответ №1:

У тебя здесь много всего происходит, и тебе не нужно время. Поскольку вы новичок, я разветвил ваше репо, чтобы вы могли увидеть гораздо более простой способ достижения той же цели. Ваши чеки в возврате также всегда будут возвращать содержимое.

 import { useEffect, useState } from "react";

export const useCountdownTimer = (date) => {
  const [seconds, setTimer] = useState(date - Date.now());
  useEffect(() => {
    const timeout = setTimeout(() => setTimer(seconds - 1), 1000);
    if (seconds <= 0) clearTimeout(timeout);
    return () => {
      clearTimeout(timeout);
    };
  }, [seconds]);

  const m = Math.floor((seconds % 3600) / 60).toString().padStart(2, "0");
  const s = Math.floor(seconds % 60).toString().padStart(2, "0");

  return {
    seconds,
    time: `${m}:${s}`
  };
};

export default function App() {
  // const date = new Date("2021-04-26T18:46:00.000Z").getTime();
  const date = Date.now()   3603; // 1 hour amp; 3 seconds from now for demo
  const { seconds, time } = useCountdownTimer(date); // date must be in seconds
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {!!seconds amp;amp; seconds >= 3600 amp;amp; <h2>TODAY</h2>}
      {!!seconds amp;amp; seconds < 3600 amp;amp; <h2>{time}</h2>}
      {seconds <= 0 amp;amp; <h2>LIVE</h2>}
    </div>
  );
}
 

https://codesandbox.io/s/reactcounterv2-forked-fsnwr?file=/src/App.js

Ответ №2:

попробуйте это https://www.npmjs.com/package/@nilevia/count-down-timer-react если вам нужен исходный код, перейдите на страницу github