javascript - 卡在一个 React 倒计时应用程序上,想知道如何正确使用 setInterval

标签 javascript reactjs

我只是想知道为什么 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;

最佳答案

每次你在计时器函数中设置状态时,你都会将其基于 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>
    );
  }
}

编辑:根据您的编辑,这是我的新解决方案,它只有应用程序组件而没有时钟组件,因为您似乎试图使用两个不同的组件执行相同的操作:

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 表单。我不确定这是否会弄乱任何事情,但是当我测试它时,这对我有用。

关于javascript - 卡在一个 React 倒计时应用程序上,想知道如何正确使用 setInterval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46289961/

相关文章:

javascript - Node JS 如何将图像与请求数据一起发布到另一个服务器/api

javascript - 如何在 HTML 或 javascript 中绘制渐变背景?

javascript - yarn 构建 - 崩溃错误 JavaScript 堆内存不足

javascript - 当值为 true 时显示选取器项目 React Native

css - 更改 material-ui 复选框的样式

java - 如何下载 java 后端发送的文件到 React 前端

javascript - ReactJs 警告 : Mutating `style` is deprecated. 考虑事先克隆它

javascript - 带有嵌入式脚本的 SVG 可缩放至浏览器可用空间

javascript - (jQuery) 使用 extend() 访问自定义属性时出现问题

reactjs - React 中的响应式设计