计时器在ReactJS中不倒计时

问题描述 投票:1回答:2

我正在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;

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

javascript reactjs timer
2个回答
0
投票

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

而是使用采用回调的secondsRemaining方法从州减去setState值。回调的第一个参数是当前状态。所以你也是:

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

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

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

2
投票

主要问题是在TimercomponentDidMount的区间回调中:

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

请注意,您不断重复使用this.props.timerPosition作为计时器位置,而不是使用当前状态。因此,您要将状态从道具设置回初始状态。

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

  1. 永远不要打电话给this.setState({foo: this.state.foo - 1})或类似的。状态更新是异步的,可以组合使用。相反,pass a callback to setState
  2. 没有任何保证在任何特定时间或特定时间间隔发生,所以不要只是减少你的计数器;相反,看看自你开始以来有多长时间,并使用该信息从你的初始计数器值中减去。这样,如果您的计时器延迟,您仍然会显示正确的值。
© www.soinside.com 2019 - 2024. All rights reserved.