2017-07-12 24 views
2

以下是部分:前组件被卸载如何清除在Reactjs组件中componentWillUnmount时超时的异步函数?

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

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

在异步回调中,检查是否设置了该标志,如果是,则立即停止。

1

您当然可以根据@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(){ 
     //... 
    } 
} 

您可以更上阅读了为什么格局已被废弃here 然而,这样做,天真地结束了双方的的getJSON为需要标志以及随后的超时,因为基本上你需要链接在一起的可取消的承诺(在那里你想停止任何一步)

一个不同的范例要考虑将使用一个可观察的链。详情请见blog