Как сбросить компонент таймера после завершения - PullRequest
0 голосов
/ 07 мая 2019

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

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

Ответы [ 2 ]

1 голос
/ 07 мая 2019

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

Во-первых, нам нужно импортировать обработчики реакции и реагирования в наш файл компонента.

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 Hooks вы можете перейти по этой ссылке https://reactjs.org/docs/hooks-intro.html.

ПРИМЕЧАНИЕ

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

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

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

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

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

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

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

0 голосов
/ 07 мая 2019

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

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 (выполнено), он просто останется на 0: 0: 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...