打字稿中的反应:计时器功能中的进度继续无限

时间:2018-02-22 10:15:25

标签: javascript reactjs typescript

构建赛车应用程序,当胜利者到达终点线(100)时,我需要创建一个简单的警报。我正在进行一场无限奔跑的比赛(如果你在console.logtimer,你会看到它。我怎样才能提醒胜利者和结束比赛?我这里只使用一名赛车手。另一个Race组件处理赛车手。

import * as React from 'react';

interface Props {
    color: string;
    avatar: string;
}

interface State {
    interval: number;
    progress: number;
}

export class Jockey extends React.Component<Props, State> {
    state: State;
    constructor(props: Props) {
        super(props);
        this.state = {
          interval: Math.floor(Math.random() * 500),
          progress: 0,
        };
    }

    componentDidMount () {
        setInterval(this.timer, this.state.interval);
    }

    timer = () => {
        this.setState({ progress: this.state.progress + 1 });
        console.log('anyhting');
        // race doesnt stop even when progress bar hits 100.
        if (this.state.progress === 100) {
            alert('you won!!');

        }
        
        // tslint:disable-next-line:no-unused-expression
        (this.state.progress >= 99) ? this.setState({ progress: 100 }) : '' ;
    }

    render() {
        return (
            <div>
                <div className="App-lane">
                    <img src={this.props.avatar} alt=""/>
                    <progress value={this.state.progress} color="red" max="100" />
                </div>
            </div>
        );
    }
}

2 个答案:

答案 0 :(得分:1)

只需存储setInterval返回的时间间隔ID,然后再使用它来呼叫clearIntervalMDN)。

componentDidMount() {
    // store interval id so that we can clear the interval later
    this.timerIntervalId = window.setInterval(this.timer, this.interval);
}

不要忘记相应地更改界面:

interface JockeyState {
    interval: number;
    progress: number;
}

// Inside timer method
    if (this.state.progress === 100) {
        window.clearInterval(this.timerIntervalId);
        alert('you won!!');
    }

此外,如果您的组件已卸载,则清除间隔可能是个好主意(但这取决于您的应用程序逻辑 - 您可能希望让竞争在后台运行)。但是,大多数情况下,您会为此创建单独的服务,因此请不要将其保留在组件中。

// how to clear on unmount
componentWillUnmount() {
    clearInterval(this.timerIntervalId);
}

修改: 而不是使用状态,答案现在在组件类中使用私有属性。

export class JockeyComponent extends React.Component<JockeyState, JockeyProps> {
    private timerIntervalId: number;


}

答案 1 :(得分:0)

清除您正在设置的间隔。 此外,在使用prevState时,最好使用setState

的函数模式

&#13;
&#13;
class Jockey extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          interval: Math.floor(Math.random() * 500),
          progress: 0,
        };
    }

    componentDidMount () {
        this.time = setInterval(this.timer, this.state.interval);
    }

    timer = () => {
        this.setState((prevState)=>{
          if(prevState.progress===100) {
            clearInterval(this.time);
            alert("Win");
            return {};  //No change in state
          } else {
            return {
              progress: prevState.progress+1
            }
          }
        });
    }
    componentWillUnmount() {
      clearInterval(this.time);  //Clear timer when the timer unmounts
    }
    render() {
        return (
            <div>
                <div className="App-lane">
                    <p>{this.state.progress}</p>
                </div>
            </div>
        );
    }
}

ReactDOM.render(<Jockey />, document.getElementById('app'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;