卡在反应倒计时应用程序上,想知道如何正确使用 setInterval

Posted

技术标签:

【中文标题】卡在反应倒计时应用程序上,想知道如何正确使用 setInterval【英文标题】:Stuck on a react countdown app and wanted to know how to utilize setInterval properly 【发布时间】:2018-02-27 14:53:29 【问题描述】:

我只是想知道为什么 setInterval 函数没有减少时间.... setInterval 是不是应该一次又一次地运行一个函数? 我希望如果我输入 100 并按提交,它会 1 比 1 下降。

 class Clock extends Component
    constructor(props)
      super(props);
      this.state = 
        seconds: 60,
      
      console.log('this.props',this.props);
      console.log('seconds',  this.state.seconds);
    

    componentWillMount()
      this.timer(this.props.time);
    

    componentDidMount()
      setInterval(()=> this.timer(this.props.time),1000);
    

    timer(time)
        console.log('new time',time )
        this.setState(seconds:time-1);
      

      render()
        return (
          <div>
          <div className="Clock-seconds">this.state.seconds seconds</div>
          </div>
        )

这是 app.jsx 文件 - 用户在此处输入以秒为单位的数字,它作为道具进入时钟。我有时间在状态。

import React, Component from 'react';
import Clock from './Clock';
import './App.css';
import Form, FormControl, Button from 'react-bootstrap';


class App extends Component
  constructor(props)
    super(props);
    this.state =
      time: '60',
      newTime: ''
    
  

  changeTime()
    this.setState(time: this.state.newTime);
  


  render()
    return (
      <div className="App">
        <div className = "App-title">
          Countdown to this.state.time
        </div>

        <Clock
         time=this.state.time
          />

        <Form inline >
          <FormControl
            className="Deadline-input"
            placeholder='new date'
            onChange=event => this.setState(newTime: event.target.value)
            />
          <Button onClick=() => this.changeTime()>
            Submit
          </Button>
        </Form>

      </div>
    )
  


export default App;

【问题讨论】:

***.com/questions/36299174/… 【参考方案1】:

每次在计时器函数中设置状态时,都是基于 this.props.time,它不会改变,状态才是真正改变的。因此,您需要根据先前的状态设置状态。另外,为什么在构造函数中将秒状态设置为 60?你不想把它设置成this.props.time吗?

我相信这就是你想要完成的:

class Clock extends Component
  constructor(props)
    super(props);
    this.state = 
      seconds: this.props.time,
    
    console.log('this.props',this.props);
    console.log('seconds',  this.state.seconds);
  

  componentWillMount()
    this.timer(this.props.time);
  

  componentDidMount()
    setInterval(()=> this.timer(),1000);
  

  timer()
    console.log('new time', this.state.seconds )
    this.setState(prevState => (
      seconds: prevState.seconds - 1
    ));
  

  render() 
    return (
      <div>
        <div className="Clock-seconds">this.state.seconds seconds</div>
      </div>
    );
  

编辑:根据您的编辑,这是我的新解决方案,它只有 App 组件而没有 Clock 组件,因为您似乎试图用两个不同的组件做同样的事情:

class App extends Component 
  constructor(props)
    super(props);
    this.state = 
      seconds: null
    
  
  componentDidMount() 
    setInterval(this.timer.bind(this), 1000);
  
  timer() 
    if (this.state.seconds) 
      this.setState(prevState => (
        seconds: prevState.seconds - 1
      ));
    
  
  handleClick(event) 
    event.preventDefault();
    this.setState(seconds: this.textInput.value);
  
  renderClock() 
    if (this.state.seconds > 0) 
      return (<div className = 'App-title'>this.state.seconds Seconds</div>);
     else if (this.state.seconds === 0) 
      return (<div className = 'App-title'>Done!</div>);
    
  
  render() 
    return (
      <div className="App">
        this.renderClock()
        <form>
          <input
            className='Deadline-input'
            placeholder='new date'
            ref=input => this.textInput = input
            type='text'>
          </input>
          <button onClick=event => this.handleClick(event)>Submit</button>
        </form>
      </div>
    );
  

这是使用普通表单,您可以将其更改为使用 Bootstrap 表单。我不确定这是否会搞砸任何事情,但是当我测试它时这对我有用。

【讨论】:

感谢您的回复,但我也有 app.jsx,其中用户正在输入新时间。我有时间在 App.jsx 状态,我将它作为道具传递。我正在使用你的代码,但它没有更新时间。让我添加 app.jsx 以便您更清楚。 你只是在做类似 之类的事情吗? 我在 app.jsx 中有 来显示倒计时。 如果你这样做,我的解决方案会起作用 你现在要做的是在两个不同的组件中保持和更改你的时间状态,这就是我的想法你的问题是。我会想办法解决的。 是的,但是用户不再输入秒数。我希望用户输入数字。

以上是关于卡在反应倒计时应用程序上,想知道如何正确使用 setInterval的主要内容,如果未能解决你的问题,请参考以下文章

如何每次在同一个视图上与 react native expo 倒计时

找到正确的结果后如何杀死重复的计时器

如何正确重置 Vue Composition Api 反应值

反应:在构造函数上绑定方法时,在 setState 内实现计时器,状态属性未定义

填充/修补角度反应形式的值

如何使用指针事件仅对滚动事件做出反应?