我正在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;
计时器不会每秒递减,只停留在原始位置。
问题是你继续使用相同的道具值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
}
主要问题是在Timer
的componentDidMount
的区间回调中:
componentDidMount(){
setInterval(() => this.startTimer(this.props.timerPosition), 1000);
}
请注意,您不断重复使用this.props.timerPosition
作为计时器位置,而不是使用当前状态。因此,您要将状态从道具设置回初始状态。
相反,您想要使用当前状态。如何使用该状态取决于您希望计时器的行为方式,但要注意两件事:
this.setState({foo: this.state.foo - 1})
或类似的。状态更新是异步的,可以组合使用。相反,pass a callback to setState
。