我正在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;
计时器不会每秒递减,只停留在原始位置。
答案 0 :(得分:2)
主要问题是Timer
的{{1}}中的区间回调:
componentDidMount
请注意,您不断重复使用componentDidMount(){
setInterval(() => this.startTimer(this.props.timerPosition), 1000);
}
作为计时器位置,而不是使用当前状态。所以你要将状态从道具设置回初始状态。
相反,您想要使用当前状态。 如何使用该状态将取决于您希望计时器的行为方式,但要注意两件事:
永远不要致电this.props.timerPosition
或类似的人。状态更新是异步的,可以组合使用。相反,pass a callback to setState
。
在任何特定时间或特定时间间隔内都不会发生任何事情,所以不要只是减少你的计数器;相反,看看自你开始以来有多长时间,并使用该信息从你的初始计数器值中减去。这样,如果您的计时器延迟,您仍然会显示正确的值。
答案 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
}