react-countdown-clock icon indicating copy to clipboard operation
react-countdown-clock copied to clipboard

How to restart the timer?

Open akhilkurnool opened this issue 7 years ago • 10 comments

How to restart on setState or any other condition or props change, I have tried to re-render the whole component using forceUpdate() but it doesn't seem to work. Using this clock for OTP countdown, need to reset when the user resend OTP.

akhilkurnool avatar Nov 21 '17 13:11 akhilkurnool

One way I found was using history to redirect to same page.

akhilkurnool avatar Nov 30 '17 04:11 akhilkurnool

This is still an open issue! The inability to restart this component is a real pain.

sjmp avatar Dec 21 '17 16:12 sjmp

No need to be quite so dramatic @sjmp . What action are you proposing would reset the timer?

I've not looked at this in a while, but I believe if the seconds prop changes, the timer will restart. It maybe that there is a bug around this that needs fixing (#45) and it might not be of use if you need to reset it to the same time.

If I find some time over the xmas holidays I will take a look.

pughpugh avatar Dec 21 '17 19:12 pughpugh

@sjmp @pughpugh Setting the same time again will not work. You can do something like this

Initial state from seconds received in props or fixed. You may also use default props instead ternary operator

constructor(props){
    super(props);

    this.state = {
      seconds: this.props.seconds ? this.props.seconds : 60,
    };
  }

Set state by adding fraction.

this.setState({
     seconds: this.getNewSeconds()
 })
getNewSeconds = () => {
    //Note: This library only restart timer when we supply different seconds
    if(this.props.seconds !== this.state.seconds) {
      return this.props.seconds;
    }else {
      return this.props.seconds + 0.0000001;
    }

zaidchauhan avatar Dec 21 '17 19:12 zaidchauhan

#45 has been fixed as well a couple of other related bugs. I'm not convinced this fully meets the requirements of resetting the timer, but might at least support a workaround for some people.

pughpugh avatar Dec 22 '17 15:12 pughpugh

Seems like a badly needed feature.

You'll have to find a way to call the following internally:

        this._clearBackground()
        this._seconds = this.props.seconds
        this._stopTimer()
        this._setupTimer()

I needed a timer that automatically reset on complete:

class ResettableTimer extends ReactCountdownClock {
  constructor(props){
    super(props)
    this._handleComplete = () => {
        // Do what you need
        this._clearBackground()
        this._seconds = this.props.seconds
        this._stopTimer()
        this._setupTimer()
    }
  }
}

miso2018 avatar Feb 10 '18 08:02 miso2018

Might not be the best approach but here is what I did to force the component to re-render and therefore restart.

import React, { Component } from 'react'
import CountDown from 'react-countdown-clock'
class CountDownTest extends Component {
  constructor() {
    super()
    this.state = {
      completions: 0
    }
  }

  onComplete = () => {
    this.setState(
      {
        completions: this.state.completions + 1
      },
      () => console.log('completions', this.state.completions)
    )
  }

  render() {
    return (
      <div>
        <CountDown
          key={this.state.completions}
          seconds={15}
          color="#000"
          alpha={0.9}
          size={300}
          onComplete={this.onComplete}
        />
      </div>
    )
  }
}

export default CountDownTest

this.state.completions updates every time the countdown is completed and by using a state property that is always changing as the value for the key attribute, forces the component to re-render.

VilliGunn avatar Aug 18 '18 00:08 VilliGunn

@VilliGunn Great solution, I'd even suggest adding it in the Readme as part of an FAQ section if there is no progress on implementing this feature into the base component.

Jeremy-coding avatar Mar 29 '19 14:03 Jeremy-coding

@pughpugh What if you will add new prop countDownStartedAt and on

componentDidUpdate(prevProps) {
    if (prevProps.seconds !== this.props.seconds || prevProps.countDownStartedAt!== this.props.countDownStartedAt) {
      this._seconds = this.props.seconds;
      this._stopTimer();
      this._setupTimer();
    }

and the only thing we have to do is change countDownStartedAt prop to restart it.

epozsh avatar Aug 21 '19 12:08 epozsh

Late to the party, but note for the people are still seeking for simple solution.

Like https://www.npmjs.com/package/react-countdown#key mentioned, just set a new key to reset the component to restart the countdown.

timgreen avatar Sep 22 '22 05:09 timgreen