计时器在ReactJS中不倒计时

时间:2018-01-01 19:15:50

标签: javascript reactjs timer

我正在ReactJS中构建一个简单的秒表应用程序(倒计时为0)。 到目前为止,我有一个输入,用户可以设置计时器应该有多长,以及一个用输入数据更新计时器状态的按钮。 但是,即使使用setInterval(),我也无法进行倒计时倒计时。

App.jsx

import React, {Component} from 'react';
import Timer from './timer';
import './app.css';
import { Form, FormControl, Button} from 'react-bootstrap';

export class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            timerPosition: '',
            newTimerPosition: '',
          };          
    }

startTimer() {
    this.setState({timerPosition:this.state.newTimerPosition})
}

    render() {
        return (
        <div className="App-title"> Stopwatch </div>
        <Timer timerPosition={this.state.timerPosition} />
        <Form inline>
        <FormControl 
        className="Deadline-input"
        onChange={event => this.setState({newTimerPosition: event.target.value})}
        placeholder='Set timer'/>
        <Button onClick={() => this.startTimer()}>Set new timer</Button>
        </Form>
        </div>
        )}



}

export default App;

Timer.jsx

import React, {Component} from 'react';
import './app.css';

export class Timer extends Component {
    constructor(props) {
        super(props);
        this.state = {
        secondsRemaining: ''
         }
    }

componentWillMount(){
    this.startTimer(this.props.timerPosition);
}

componentDidMount(){
    setInterval(() => this.startTimer(this.props.timerPosition), 1000);
}


startTimer(timerCallback) {
    this.setState({secondsRemaining: timerCallback --})
}



render() { 
return (
<div>

<div></div>
{this.state.secondsRemaining} seconds remaining
</div>


)}

}


export default Timer;

计时器不会每秒递减,只停留在原始位置。

2 个答案:

答案 0 :(得分:2)

主要问题是Timer的{​​{1}}中的区间回调:

componentDidMount

请注意,您不断重复使用componentDidMount(){ setInterval(() => this.startTimer(this.props.timerPosition), 1000); } 作为计时器位置,而不是使用当前状态。所以你要将状态从道具设置回初始状态。

相反,您想要使用当前状态。 如何使用该状态将取决于您希望计时器的行为方式,但要注意两件事:

  1. 永远不要致电this.props.timerPosition或类似的人。状态更新是异步的,可以组合使用。相反,pass a callback to setState

  2. 在任何特定时间或特定时间间隔内都不会发生任何事情,所以不要只是减少你的计数器;相反,看看自你开始以来有多长时间,并使用该信息从你的初始计数器值中减去。这样,如果您的计时器延迟,您仍然会显示正确的值。

答案 1 :(得分:0)

问题是你继续使用相同的道具值secondsRemaining。每次在prop this.props.timerPosition中递减相同的值。所以状态值secondsRemaining永远不会改变。

使用采用回调的secondsRemaining方法从状态减少setState值。回调的第一个参数是当前状态。所以你这样做:

this.setState((prevState, props) => {
    return { secondsRemaining: prevState.secondsRemaining - 1 };
  }); 

您还需要将初始状态值设置为提供的道具值:

componentWillMount(){
    this.setState({ secondsRemaining: this.props.timerPosition });
    ... other code
}