Как сбросить компонент таймера после завершения

Я пытаюсь создать компонент таймера, используя пакет 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>;
     //}
};

Я хочу, чтобы он начинался с обратного отсчета из списка, а затем, когда он был завершен, переходил к следующему значению расписания из списка.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
2 775
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это полное изменение по сравнению с предыдущим ответом, в котором использовался компонент на основе классов.

Во-первых, нам нужно импортировать 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.

ПРИМЕЧАНИЕ

  1. Вам нужен способ узнать, в какое время вы сейчас находитесь, поэтому в вашем компоненте у вас будет две вещи. Список времени (times) в виде массива должен передаваться как реквизит, как это предлагается в приведенном выше коде, индекс текущего времени (currentTimeIndex) как целое число и текущее время (currentTime) как объект даты.

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

  3. Ключевое свойство компонента обратного отсчета, оно должно меняться каждый раз, когда вы хотите сбросить таймер обратного отсчета, и, поскольку мы увеличиваем индекс, чтобы перейти к следующему разу, мы просто будем использовать индекс текущего времени.

  4. Я сократил код вашего средства визуализации, чтобы вы могли отображать то, что вам нужно, в одной и той же функции, за исключением случаев, когда вы будете добавлять туда гораздо больше кода, чем это.

  5. Это использует функциональный компонент с хуки для поддержания состояния.

  6. Дата согласно документации может быть объектом даты.

Надеюсь, это поможет ответить на ваш вопрос.

Извините, я должен был указать это, но я пытаюсь сделать это как функциональный компонент. Но это было очень полезно. Я пытаюсь перевести это, но я не уверен, где я иду не так.

Daniyal Maniar 07.05.2019 22:08

Я разместил свое текущее состояние ниже

Daniyal Maniar 07.05.2019 22:32

Да, это не будет работать прямо из коробки, но вы можете использовать React Hooks для поддержания состояния, и я обновлю свой ответ и добавлю, чтобы сделать его функциональным компонентом, используя реагирующие хуки для поддержания состояния, чтобы показать вам.

Daniel Barde 07.05.2019 22:35

@DaniyalManiar Я обновил свой ответ, чтобы показать, как вы можете использовать функциональные компоненты для достижения того же самого, я использую React Hooks для поддержания состояния, я оставил ссылку на документы, которые вы никогда раньше не использовали React Hooks. Надеюсь, поможет.

Daniel Barde 07.05.2019 22:51

Спасибо, это немного помогло

Daniyal Maniar 08.05.2019 18:33

@DaniyalManiar Рад, что смог помочь! :)

Daniel Barde 09.05.2019 17:20

Я предполагаю, что мой переведенный компонент будет выглядеть так

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

Другие вопросы по теме