【问题标题】:React and SetInterval (FCC Pomodoro Timer..)React 和 SetInterval (FCC Pomodoro Timer..)
【发布时间】:2020-03-11 06:07:35
【问题描述】:

我在使用 setInterval 和 React 时遇到了一些问题。

基本上,我正在尝试为 FreeCodeCamp 构建番茄钟,而 setInterval 无法识别该函数已定义.. 链接如下。

https://codepen.io/paalpwmd/pen/yLNJEMv?editors=1111

基本上 - 我希望计时器方法从总长度状态中减去 1000 毫秒,直到长度为 0。

我得到的错误是这个..

TypeError: this.tick is not a function 
 at https://cdpn.io/boomboom/v2/index.html?editors=1111&key=iFrameKey-713a6d83-4480-ba30-a898-c7e72b527740:28

我还尝试将设置间隔函数直接放在计时器中(像这样),但我收到一个错误,提示 this.state 未定义。

timer(){
    setInterval(function() {
      this.setState({
      length: this.state.length - 1000 
}), 1000)
}

ES6 和 ES5 的语法我都试过了,这是绑定在构造函数上的。

我认为这与 React 绑定 this 的方式有关。我在这里做错了什么?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    setInterval 回调function 更改为arrow function

    setInterval 将调用回调函数时,this 将引用setInterval object

    如果状态更新依赖于先前的状态,则始终在 setState 中使用callback

    试试这个。

      timer() {
        setInterval(() => {
          this.tick();
          console.log("tick");
        }, 1000)
      }
    

    工作示例:

    class PomTimer extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          break: 300000,
          length: 1500000,
          clockFace: ''
        }
        this.clockify = this.clockify.bind(this);
        this.timer = this.timer.bind(this);
        this.reset = this.reset.bind(this);
        this.tick = this.tick.bind(this);
      }
    
      reset() {
        this.setState({
          break: 300000,
          length: 1500000
        })
        this.clockify();
      }
    
      tick() {
        //console.log("tick: " + this.state.length);
        if (this.state.length > 0) {
          this.setState( (preState) => {
            return {
                length: preState.length - 1000
            }
          })
    
        } else {
    
        }
      }
    
      clockify() {
        let minutes = Math.floor(this.state.length / 60000);
        let seconds = (this.state.length % 60000) / 1000
        this.setState({
          clockFace: `${minutes}:${seconds}`
        })
      }
    
    
      timer() {
        setInterval(() => {
          this.tick();
        }, 1000)
      }
    
      componentDidMount() {
        this.clockify();
      }
      render() {
        return <div>
          <h1>Pomodoro Clock</h1>
          <div id="break-label">
            <div id="break-increment" onClick={this.breakInc}>+</div>
            <p id="break-length">Break Length: {this.state.break / 60000}</p>
            <div id="break-decrement" onClick={this.breakDec}>-</div>
          </div>
    
          <div id="session-label">
            <div id="session-increment" onClick={this.sessionInc}> + </div>
            <p id="session-length">Session Length {Math.ceil(this.state.length / 60000)} ({this.state.length})</p>
            <div id="session-decrement" onClick={this.sessionDec}> - </div>
    
          </div>
          <div id="session">
    
            <p id="time-left"> Session: {this.state.clockFace} </p>
          </div>
          <button onClick={this.clockify}>test</button>
          <button onClick={this.resetTimer}>Reset</button>
          <button onClick={this.timer}>Timer</button>
        </div>
      }
    }
    ReactDOM.render(<PomTimer />, document.getElementById("react-root"));
    #react-root {
      width: 50%;
      display: flex;
      margin: auto;
      border: 2px solid black;
      border-radius: 50px;
      justify-content: center;
      
    }
    body {
      background-color: #1E555C;
      font-family: 'Verdana'
    }
    
    #break-increment, #break-decrement, #session-increment, #session-decrement{
      cursor: pointer;
      margin: 0px 5px;
      border: 1px solid black;
      border-radius: 5px;
      width: 20px;
      height: 20px;
      text-align: center;
      background-color: #1E777C;
    }
    
    #session-label, #break-label, #session {
       display: flex;
      flex-direction: row;
      justify-content: center;
      padding-top: 50px;
    }
    #break-length, #session-length{
    margin: 0;
    }
    
    #time-left {
      font-size: 2rem;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="react-root">

    【讨论】:

      猜你喜欢
      • 2020-09-07
      • 2011-12-17
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2022-12-30
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多