#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