在Typescript中的反应:进度继续在计时器功能中无穷大



构建赛车应用程序,当获胜者达到终点线(100(时,我需要创建一个简单的警报。我将获得无限的跑步比赛(如果您在timer中的console.log,您会看到它(。我如何提醒获胜者和结束比赛?我在这里只使用一名赛车手。另一个种族组成部分处理赛车手。

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>
        );
    }
}

只需存储setInterval返回的间隔ID,然后使用它来调用clearInterval(MDN(。

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;

}

清除您设置的间隔。另外,当使用Prevstate时,最好使用setState

的功能模式。

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'));
<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>

最新更新