猿问

存储在状态中的箭头函数

所以我有这个问题,我不知道这是一个错误的概念还是这个概念的糟糕实现。我用 freecodecamp.org 做了番茄钟,这迫使我从普通的js和 React 组件中使用 setInterval() 函数。


在番茄工作组件内部,每次将其安装在DOM树中时,都应该运行一个 setInterval 检查状态和时钟,具体取决于组件的状态。事实上,我可以看到状态变量的变化(多亏了 React 调试工具),但间隔不起作用


componentdidmount在将组件呈现在DOM树中并检查状态.status之后运行,如果它的真实检查要运行的周期,无论是会话还是中断时钟。一个计时器结束后,另一个计时器应立即开始。


此计时器或间隔存储在组件状态中,然后从 this.state.间隔状态中清除。



class Pomodoro extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

     session:1500,

     break:300,

     cycle:true,

     status:false,

     sessionClock:1500,

     breakClock:300,

     interval:0,

    }

 this.addSessionTime = this.addSessionTime.bind(this);

 this.decSessionTime = this.decSessionTime.bind(this);

this.addBreakTime = this.addBreakTime.bind(this);

 this.decBreakTime = this.decBreakTime.bind(this);

 this.pause = this.pause.bind(this);

 this.reset = this.reset.bind(this);

  }


/*Avoided all the other binded functions since they are just setStates*/



componentDidMount() {  


if (this.state.status) 

{



  if (this.state.cycle /* cycle true = session */) 



      { 

        this.setState({

          interval:(setInterval( ()=> {



      if (!this.state.status/*status true = clock running*/ ) {clearInterval(this.state.interval);}

      else 


        {/*begin session clock*/

          if (this.state.sessionClock > 1 /*check if is the last second*/)

          {

        this.setState({sessionClock: this.state.sessionClock - 1});

                      /*take away a second from sessionClock*/

          }


       else {this.setState({cycle:!this.state.cycle, sessionClock:this.state.session}) }

        }                  /*change cycle and restart sessionclock*/


                                                  }

    ,1000)

      )})}


时钟由于将集合间隔保存到组件状态或由于其他原因而无法正常工作?


编辑


添加了一个笔,以便您可以看到实时版本和状态的变化


https://codepen.io/bigclown/pen/bGEpJZb


编辑二


删除了组件didmount方法并将内容移动到 pause() 方法,但现在两个时钟同时运行,时钟运行速度比预期的要快(可能是 react 中的异步状态更新带来了问题?


侃侃尔雅
浏览 100回答 2
2回答

蛊毒传说

问题是您对 的用法。它在挂载组件时被调用,这意味着在用户可以与屏幕交互之前调用它。componentDidMount您的支票if (this.state.status) 永远不会是真的,因为你的状态设置为假。查看您的代码,我假设您的意思是将状态切换为真,并且您认为其中的代码将运行。statuscomponentDidMount但是,您应该做的是将代码移动到函数中,因为这实际上是时钟的触发器。pause()从那里,您可以执行类似于以下内容的操作:  pause() {    if (this.state.status === false) {       // Start your clock, whilst checking `cycle`    } else {       clearInterval(this.state.interval);    }  }这是一个笔,我已经重构了你的代码,但基本上将所有逻辑都移到了.https://codepen.io/stephenyu-the-encoder/pen/zYrqQYEPause我已将所有时钟更改为从5秒开始,因此看到它工作得更快。

四季花海

我怀疑您的时钟同时运行并且计时器关闭的问题是由于在启动新计时器之前没有停止旧计时器。您可能要查找的是组件更新方法。此方法允许您将上一个状态与当前状态进行比较,并进行相应的更改。使用该方法,您可以检查我们何时从休息时间切换到会话时间,然后停止旧计时器以启动新计时器,如下所示:  componentDidUpdate(prevProps, prevState) {    // We need to check that the new state is different from the old state    // if it is, stop the old timer, and kick off the new one    if (prevState.cycle !== this.state.cycle) {      clearInterval(this.state.interval);      if (this.state.cycle) {        // If the cycle switched to session, start the session timer        this.startSession();      } else {        // If the cycle switched to break, start the break timer        this.startBreak();      }    }  }这样,只要您的会话或中断计时器达到0,您就会切换,您将始终启动新的计时器。this.state.cycle在此处查看我的新代码笔,了解功能齐全的代码
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答