React应用中的setInterval

我在React还是很新,但是我一直在慢慢地学习,遇到了一些我坚持的事情。

我正在尝试在React中构建一个“计时器”组件,老实说,我不知道我是否做得正确(或有效)。在下面我的代码,我设置状态来返回一个对象{ currentCount: 10 },并已与玩弄componentDidMountcomponentWillUnmountrender我只能得到状态,以“倒计时”,从10到9。

分两部分的问题:我怎么了?并且,有没有使用setTimeout的更有效方法(而不是使用componentDidMountcomponentWillUnmount)?

先感谢您。

import React from 'react';

var Clock = React.createClass({

  getInitialState: function() {
    return { currentCount: 10 };
  },

  componentDidMount: function() {
    this.countdown = setInterval(this.timer, 1000);
  },

  componentWillUnmount: function() {
    clearInterval(this.countdown);
  },

  timer: function() {
    this.setState({ currentCount: 10 });
  },

  render: function() {
    var displayCount = this.state.currentCount--;
    return (
      <section>
        {displayCount}
      </section>
    );
  }

});

module.exports = Clock;
神奇Davaid2020/03/12 17:02:26

谢谢@dotnetom,@ greg-herbowicz

如果返回“ this.state未定义”-绑定计时器函数:

constructor(props){
    super(props);
    this.state = {currentCount: 10}
    this.timer = this.timer.bind(this)
}
西里Davaid2020/03/12 17:02:26

我发现您的代码有4个问题:

  • 在您的计时器方法中,您始终将当前计数设置为10
  • 您尝试在render方法中更新状态
  • 您没有使用setState方法来实际更改状态
  • 您没有在状态中存储intervalId

让我们尝试解决该问题:

componentDidMount: function() {
   var intervalId = setInterval(this.timer, 1000);
   // store intervalId in the state so it can be accessed later:
   this.setState({intervalId: intervalId});
},

componentWillUnmount: function() {
   // use intervalId from the state to clear the interval
   clearInterval(this.state.intervalId);
},

timer: function() {
   // setState method is used to update the state
   this.setState({ currentCount: this.state.currentCount -1 });
},

render: function() {
    // You do not need to decrease the value here
    return (
      <section>
       {this.state.currentCount}
      </section>
    );
}

这将导致计时器从10减少到-N。如果您希望计时器减少到0,则可以使用经过稍微修改的版本:

timer: function() {
   var newCount = this.state.currentCount - 1;
   if(newCount >= 0) { 
       this.setState({ currentCount: newCount });
   } else {
       clearInterval(this.state.intervalId);
   }
},