简体   繁体   中英

how to implement setTimeInterval in React?

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 minus one every one second 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.

for now i am in the second feature to implement setTimeInterval. I have implement the input, but when i click start, the displayed number should subtract 1 every 1 second. but then the error occurs.

also can anyone give me a hand how to implement when i click the button and then change the text value from 'start' to 'stop'?

TypeError: Cannot read property 'id' of undefined
(anonymous function)
src/App.js:40
  37 | <div>
  38 |   {this.state.details.map(detail => {
  39 |     return (
> 40 |       <div key={detail.id}>
     | ^  41 |         Number:{detail.number}
  42 |         <input
  43 |           type="number"

Here is my code.

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      details: [{ id: 1, number: "" }],
      type: "start"
    };
  }
  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.timer = setInterval(
      () =>
        this.setState({
          details: this.state.details.map(detail => {
            detail.number = parseInt(detail.number) - 1;
          })
        }),
      1000
    );
  };

  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}
              />
              <button onClick={() => this.handleClick()}>
                {this.state.type}
              </button>
            </div>
          );
        })}
      </div>
    );
  }
}

export default App;

In the handleClick function, you would want to use the prevState as you have access to prevState from within your setState call.

enter code herehandleClick = () => {
this.timer = setInterval(
  () =>
    this.setState(prevState => {
      details: prevState.details.map(detail => {
        console.log('detail', detail);
        detail.number = parseInt(detail.number) - 1;
      });
    }),
  1000
);};

Now, it should work like a charm.

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