【问题标题】:How to reset the timer component upon completion如何在完成后重置计时器组件
【发布时间】:2019-09-25 11:44:19
【问题描述】:

我正在尝试使用 react-countdown-now 包构建一个计时器组件:https://www.npmjs.com/package/react-countdown-now#key

我在重置计时器以使其进入计划中的下一个时间时遇到问题。

我一直在尝试在 props 中使用 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 reactjs ecmascript-6 timer


    【解决方案1】:

    只需要更改key属性key={new values or updated value}的值,自动重新设置定时器。

    键 这是 React 的内部组件 props 之一,用于标识组件。但是,我们可以利用这种行为,例如,通过传入一个新的字符串或数字来重新开始倒计时。https://www.npmjs.com/package/react-countdown

    【讨论】:

      【解决方案2】:

      这与使用基于类的组件的前一个答案完全不同。

      首先,我们需要将 react 和 react 钩子导入到我们的组件文件中。

      import React, { useState } from 'react';
      

      接下来,我们将声明一个 react 函数组件并使用 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 hooks 还是有点新,所以为了更好地理解 React Hooks,你可以点击这个链接https://reactjs.org/docs/hooks-intro.html

      注意

      1. 您需要一种方法来判断您当前的工作时间,因此在您的组件中您将拥有两件事。时间列表(times)作为数组,这应该作为上面代码中建议的道具传递,当前时间的索引(currentTimeIndex)作为整数,当前时间(currentTime)作为一个日期对象。

      2. 您需要使用onComplete 属性来监听计时器何时达到零以定义回调方法,当倒数计时器完成时,我们不会更新组件的状态。

      3. Countdown 组件上的一个关键属性,这意味着每次您想要重置倒数计时器时都会更改,因为我们正在增加索引以转到下一次我们将简单地使用索引当前时间。

      4. 我减少了渲染器的代码,以便您可以在同一个函数中渲染您需要的内容,除非您将在其中添加更多代码。

      5. 这是使用带有hooks的函数组件来维护状态。

      6. 文档中的日期可以是日期对象。

      希望这有助于回答您的问题。

      【讨论】:

      • 对不起,我应该指定这个,但我正试图将其作为一个功能组件。但这非常有帮助。我正在尝试翻译它,但我不确定我哪里出错了。
      • 我在下面发布了我的当前状态
      • 是的,它不能开箱即用,但您可以使用 React Hooks 来维护状态,我将更新我的答案并添加使用 react hooks 使其成为功能组件保持状态给你看。
      • @DaniyalManiar 我已经更新了我的答案,以展示如何使用函数组件来实现相同的目标,我正在使用 React Hooks 来维护状态,我已经留下了指向我拥有的文档的链接'以前从未使用过 React Hooks。希望对您有所帮助。
      • 感谢这帮助了很多
      【解决方案3】:

      我猜我翻译后的组件应该是这样的

      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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-06
        • 2020-12-06
        • 2021-11-12
        • 1970-01-01
        相关资源
        最近更新 更多