Я пытаюсь создать компонент таймера, используя пакет response-countdown-now: https://www.npmjs.com/package/react-countdown-now#key.
У меня возникли проблемы с сбросом таймера, чтобы он перешел к следующему времени в расписании.
Я пытался использовать ключевое свойство в реквизитах, он передал его в массиве раз, чтобы дождаться (это было в документации). На самом деле я бы получил эти значения расписания с помощью метода на стороне сервера.
В настоящее время у меня есть
Компонент:
<Countdown
date = {Date.now() + 5000}
key = {timeDelays}
intervalDelay = {0}
precision = {3}
renderer = {timerRenderer}
/>
Вспомогательные функции и ценности:
//These time values are most probably going to be in JSON format,
//and probably will contain EPOCH times for scheduled events
const timeDelays = [2000,4000,3000,15789,2345794];
// Random component
const Completionist = () => <span>You are good to go!</span>;
// Renderer callback with condition
const timerRenderer = ({ hours, minutes, seconds, completed }) => {
// if (completed) {
// Render a completed state
// return <Completionist />;
// } else {
// // Render a countdown
return <span>{hours}:{minutes}:{seconds}</span>;
//}
};
Я хочу, чтобы он начинался с обратного отсчета из списка, а затем, когда он был завершен, переходил к следующему значению расписания из списка.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это полное изменение по сравнению с предыдущим ответом, в котором использовался компонент на основе классов.
Во-первых, нам нужно импортировать react и react hooks в файл нашего компонента.
import React, { useState } from 'react';
Далее мы объявим компонент функции реакции и будем использовать хуки реакции для поддержания состояния.
function MyCountdownTimer({ times }) {
// a hook for the current time index
const [currentTimeIndex, setCurrentTimeIndex] = useState(0);
// a hook for the current time
const [currentTime, setCurrentTime] = useState(null);
// return a render
return (
<Countdown
date = {currentTime}
key = {currentTimeIndex}
onComplete = {() => {
// dont's move to next time if just done with last time
if (times.length - 1 <= times.indexOf(currentTime)) return;
// move to next time index
setCurrentTimeIndex(currentTimeIndex + 1);
// reset current time
setCurrentTime(new Date(times[currentTimeIndex + 1]));
}}
renderer = {({ hours, minutes, seconds, completed }) => {
// render completed
if (completed) return <span>You are good to go!</span>;
// render current countdown time
return <span>{hours}:{minutes}:{seconds}</span>;
}}
/>
);
}
Реализация этого будет выглядеть примерно так.
let times = [...] // an array of times
<MyCountdownTimer times = {times} />
Хуки React все еще немного новы, поэтому для лучшего понимания хуков React вы можете перейти по этой ссылке https://reactjs.org/docs/hooks-intro.html.
ПРИМЕЧАНИЕ
Вам нужен способ узнать, в какое время вы сейчас находитесь, поэтому в вашем компоненте у вас будет две вещи. Список времени (times) в виде массива должен передаваться как реквизит, как это предлагается в приведенном выше коде, индекс текущего времени (currentTimeIndex) как целое число и текущее время (currentTime) как объект даты.
Вам нужно будет прослушать, когда таймер достигнет нуля, используя свойство onComplete, чтобы определить метод обратного вызова, мы не обновляем состояние компонента, когда таймер обратного отсчета завершен.
Ключевое свойство компонента обратного отсчета, оно должно меняться каждый раз, когда вы хотите сбросить таймер обратного отсчета, и, поскольку мы увеличиваем индекс, чтобы перейти к следующему разу, мы просто будем использовать индекс текущего времени.
Я сократил код вашего средства визуализации, чтобы вы могли отображать то, что вам нужно, в одной и той же функции, за исключением случаев, когда вы будете добавлять туда гораздо больше кода, чем это.
Это использует функциональный компонент с хуки для поддержания состояния.
Дата согласно документации может быть объектом даты.
Надеюсь, это поможет ответить на ваш вопрос.
Я разместил свое текущее состояние ниже
Да, это не будет работать прямо из коробки, но вы можете использовать React Hooks для поддержания состояния, и я обновлю свой ответ и добавлю, чтобы сделать его функциональным компонентом, используя реагирующие хуки для поддержания состояния, чтобы показать вам.
@DaniyalManiar Я обновил свой ответ, чтобы показать, как вы можете использовать функциональные компоненты для достижения того же самого, я использую React Hooks для поддержания состояния, я оставил ссылку на документы, которые вы никогда раньше не использовали React Hooks. Надеюсь, поможет.
Спасибо, это немного помогло
@DaniyalManiar Рад, что смог помочь! :)
Я предполагаю, что мой переведенный компонент будет выглядеть так
const WebPage = (props) => {
const timerState = {
times:[Date.now()+5000,Date.now()+12000,Date.now()+17000,Date.now()+22000],
currentTimeIndex: 0,
currentTime: Date.now(),
} ;
const timerRenderer = ({ hours, minutes, seconds, completed }) => {
if (completed) return <span> No more Scheduled time</span>;
return <span>{hours}:{minutes}:{seconds}</span>;
};
const completeTime = () => {
if (timerState.times.length - 1 <= times.indexOf(timerState.currentTime)) return;
// move to next time
timerState.currentTimeIndex++;
timerState.currentTime = new Date(timerState.times[timerState.currentTimeIndex+1])
};
return (
<Countdown
date = {timerState.currentTime}
key = {timerState.currentTimeIndex}
onComplete = {completeTime}
intervalDelay = {0}
precision = {3}
renderer = {timerRenderer}
/>
)
}
Это не совсем работает, так как по умолчанию оно переходит в «Больше запланированного времени», и если я избавлюсь от if (completed), он просто останется на 0: 0: 0.
Просто вам нужно изменить значение ключевого атрибута key = {new values or updated value}, чтобы автоматически сбросить таймер.
key This is one of React's internal component props and is used to identify the component. However, we can leverage this behaviour and use it to, for example, restart the countdown by passing in a new string or number.https://www.npmjs.com/package/react-countdown
Извините, я должен был указать это, но я пытаюсь сделать это как функциональный компонент. Но это было очень полезно. Я пытаюсь перевести это, но я не уверен, где я иду не так.