Javascript 在ReactJS中计时器不倒计时

Javascript 在ReactJS中计时器不倒计时,javascript,reactjs,timer,Javascript,Reactjs,Timer,我正在ReactJS中构建一个简单的秒表应用程序(倒计时到0)。 到目前为止,我有一个输入,用户可以设置定时器应该有多长,还有一个按钮,可以用输入数据更新定时器状态。 但是,即使使用setInterval(),我也无法进行计时器倒计时 App.jsx import React, {Component} from 'react'; import Timer from './timer'; import './app.css'; import { Form, FormControl, Button}

我正在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;
import React,{Component}来自'React';
从“./Timer”导入计时器;
导入“/app.css”;
从“react bootstrap”导入{Form,FormControl,Button};
导出类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
时间位置:“”,
新的时间位置:“”,
};          
}
startTimer(){
this.setState({timerPosition:this.state.newTimerPosition})
}
render(){
返回(
秒表
this.setState({newTimerPosition:event.target.value})
占位符=“设置计时器”/>
this.startTimer()}>设置新计时器
)}
}
导出默认应用程序;
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;
import React,{Component}来自'React';
导入“/app.css”;
导出类计时器扩展组件{
建造师(道具){
超级(道具);
此.state={
第二次维护:“”
}
}
组件willmount(){
this.startTimer(this.props.timerPosition);
}
componentDidMount(){
setInterval(()=>this.startTimer(this.props.timerPosition),1000;
}
startTimer(timerCallback){
this.setState({secondsRemaining:timerCallback--})
}
render(){
返回(
{this.state.secondsRemaining}剩余秒数
)}
}
导出默认定时器;

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

主要问题在于
计时器
组件的
安装中的间隔回调:

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

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

  • 永远不要调用
    this.setState({foo:this.state.foo-1})
    或类似的函数。状态更新是异步的,可以组合使用。相反

  • 在任何特定的时间或特定的时间间隔内都不会发生任何事情,所以不要只是减少计数器;取而代之的是,看看从开始到现在有多长时间了,然后用这些信息从初始计数器值中减去。这样,如果计时器延迟,您仍然显示正确的值


  • 问题是您一直在使用相同的道具值
    secondsRemaining
    。每次在prop
    this.props.timerPosition
    中递减相同的值。因此状态值
    secondsRemaining
    永远不会更改

    相反,使用接受回调的
    setState
    方法从状态中减少
    secondsRemaining
    值。回调的第一个参数是当前状态。所以你会:

    this.setState((prevState, props) => {
        return { secondsRemaining: prevState.secondsRemaining - 1 };
      }); 
    
    您还需要将初始状态值设置为提供的道具值:

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

    请将问题中的代码简化为演示问题的代码,最好是使用堆栈片段(
    []
    工具栏按钮)运行的代码。堆栈代码段支持React,包括JSX。谢谢,现在正在倒计时,但是它忽略了原始状态(timerPosition)。因此,如果我在表单中输入了一些内容(更新timerPosition),则secondsRemaining状态不会更新。如果您能提供进一步帮助,我将不胜感激。您需要通过设置
    状态来设置初始状态。从
    组件中提供的道具值中,secondsRemaining
    (使用setState)将安装
    。我会更新我的答案不幸的是,这没有改变任何事情