6

这是组件:

class ChartComp extends Component{
    constructor(props){
        super(props);
        this.timer = null;
        this.loadData = this.loadData.bind(this);
    }

    componentWillMount(){
        this.loadData();
    }

    componentWillUnmount(){
        if(this.timer){
            clearTimeout(this.timer);
        }
    }

    loadData(){
        //...
        getJSON(url, msg=>{ //get data from server
            if(msg.success){
                //...
                this.timer = setTimeout(()=>{this.loadData()}, 30000); //get data and rerender the component every 30s
            }
        })
    }

    render(){
        //...
    }
}

clearTimeout 函数将在组件卸载之前调用。但是计时器处于异步功能中,并且在我得到服务器的响应后再次启动。那么我怎样才能使 clearTimeout 工作呢?

4

2 回答 2

5

在你的班级里面设置一个标志componentWillUnmount

在您的异步回调中,检查该标志是否已设置,如果是,请立即停止。

于 2017-07-12T16:52:09.770 回答
4

您当然可以按照@SLaks 的建议设置一个标志。这类似于 isMounted 模式。**注意我改成componentdidmount,我认为这是一个更好的模式**

class ChartComp extends Component{
    constructor(props){
        super(props);
        this.timer = null;
        this.loadData = this.loadData.bind(this);
    }

    componentDidMount() {
      this._mounted = true;
      this.loadData();
    }

    componentWillUnmount(){
        this._mounted = false;
        if(this.timer){
            clearTimeout(this.timer);
        }
    }

    loadData(){
        //...
        getJSON(url, msg=>{ //get data from server
            if(msg.success && this._mounted){
                //...
                this.timer = setTimeout(()=>{this.loadData()}, 30000); //get data and rerender the component every 30s
            }
        })
    }

    render(){
        //...
    }
}

您可以在此处阅读有关为什么不推荐使用该模式的更多信息 但是,天真地这样做最终需要在 getJSON 以及随后的超时上都带有标志,因为基本上您需要将可取消的承诺链接在一起(您想在其中停止任何步骤道路)

要考虑的另一种范式是为此使用可观察的链。有关详细信息,请参阅此博客

于 2017-07-12T18:15:30.543 回答