简体   繁体   中英

how to stop a timer in setInterval by click then resume by click again?

I am new to react, I am trying to write a react component, component has several features.

  1. user can input a random number, then number will be displayed in the page too.
  2. implement a button with text value 'start', once click the button, the number value displayed will reduce one every 1second and the text value will become 'stop'.
  3. continue click button, minus one will stop and text value of button will become back to 'start'.
  4. when number subtract to 0 will automatically stop itself.

I have implemented the first and second feature. but when I try to click stop to stop number from reducing 1, it does not work.

I am wondering since I used type=true/false to indicate the state of type is start or stop. Because in the start state, number should automatically reduce 1. And on the stop state, reducing 1 should stop. So, the timer function should accurate according to the state of type.

Also I am not sure if I used clearInterval method right.

I really appreciate if someone could give me a hand.

code is here:

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          details: [{ id: 1, number: "" }],
          type: false
        };
        this.handleClick = this.handleClick.bind(this);
      }
      changeNumber = (e, target) => {
        this.setState({
          details: this.state.details.map(detail => {
            if (detail.id === target.id) {
              detail.number = e.target.value;
            }
            return detail;
          })
        });
      };

      handleClick = () => {
        this.setState(prevState => ({
          type: !prevState.type
        }));
        if (this.state.type === false) {
          var myTimer = setInterval(
            () =>
              this.setState({
                details: this.state.details.map(detail => {
                  if (detail.id) {
                    detail.number = parseInt(detail.number) - 1;
                  }
                  return detail;
                })
              }),
            1000
          );
        } else if (this.state.type === true) {
          clearInterval(myTimer);
        }
      };

      render() {
        return (
          <div>
            {this.state.details.map(detail => {
              return (
                <div key={detail.id}>
                  Number:{detail.number}
                  <input
                    type="number"
                    onChange={e => this.changeNumber(e, detail)}
                    value={detail.number}
                  />
                  <input
                    type="button"
                    onClick={() => this.handleClick()}
                    value={this.state.type ? "stop" : "start"}
                  />
                </div>
              );
            })}
          </div>
        );
      }
    }

    export default App;

You need to declare var myTimer outside of the handleClick() function.

So it's something like:

var myTimer;

...

handleClick = () => {
        this.setState(prevState => ({
          type: !prevState.type
        }));
        if (this.state.type === false) {
          myTimer = setInterval(
            () =>
              this.setState({
                details: this.state.details.map(detail => {
                  if (detail.id) {
                    detail.number = parseInt(detail.number) - 1;
                  }
                  return detail;
                })
              }),
            1000
          );
        } else if (this.state.type === true) {
          clearInterval(myTimer);
        }
      };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM