Farzan Najipour
Farzan Najipour

Reputation: 2503

ReactJs - Countdown reset unexpectedly

I've used Countdown on my project and it works like a charm. but when I combined it with simple input, it would be restart whenever my input changes. I want to restart it only and only if time over. Here is my code:

import React from 'react';
import { Input } from 'reactstrap';
import Countdown from 'react-countdown-now';
import { connect } from 'react-redux';

class Foo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      code: '',
      disabled: false,
    };
    this.update = this.update.bind(this);
  }

  update(e) {
    this.setState({ code: e.target.value });
  }

  render() {
    return (
      <div>
        <Input
          className="text-center activationCode__letter-spacing"
          maxLength="4"
          type="text"
          pattern="\d*"
          id="activationCode__input-fourth"
          bsSize="lg"
          value={this.state.code}
          onChange={this.update}
        />{' '}
        <Countdown date={Date.now() + 120000} renderer={renderer} />
      </div>
    );
  }
}

const renderer = ({ minutes, seconds, completed }) => {
  if (completed) {
    return <p>reset</p>;
  }
  return (
    <p>
      {minutes}:{seconds}
    </p>
  );
};

const mapStateToProps = state => ({
  user: state.auth,
});

export default connect(
  mapStateToProps,
  null,
)(Foo);

Any suggestion?

Upvotes: 1

Views: 1180

Answers (1)

Stephan Olsen
Stephan Olsen

Reputation: 1815

The reason why your counter is restarting, is because when you change the input field you're updating your state. Updating the state will cause a rerender which ultimately executes the Date.now() function again.

A solution for your problem would be to move the date for your countdown up in your constructor, so it is only set once, and then in your render function reference it through state.

constructor(props) {
super(props);
this.state = {
  code: '',
  disabled: false,
  date: Date.now() + 120000
};
this.update = this.update.bind(this);
}

...

render() {
  return (
    <div>
      <Input
        className="text-center activationCode__letter-spacing"
        maxLength="4"
        type="text"
        pattern="\d*"
        id="activationCode__input-fourth"
        bsSize="lg"
        value={this.state.code}
        onChange={this.update}
      />{' '}
      <Countdown date={this.state.date} renderer={renderer} />
    </div>
  );
}

Upvotes: 5

Related Questions