2017-06-09 22 views
4

我有一个名为“Item”的组件,该组件在安装时创建并调用一个承诺。在ReactJS中卸载组件时取消承诺

class Item extends React.Component{ 
    constructor(props){ 
     super(props) 
     this.onClick = this.onClick.bind(this) 

     this.prom = new Promise((resolve, reject) => { 
      setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000) 
     }) 
    } 

    componentDidMount(){ 
     this.prom.then((success) => { 
      console.log(success) 
     }) 
    } 

    componentWillUnmount(){ 
     console.log("unmounted") 
    } 

    onClick(e){ 
     e.preventDefault() 
     this.props.remove(this.props.id) 
    } 

    render(){ 
     return (
      <h1>Item {this.props.id} - <a href="#" onClick={this.onClick}>Remove</a></h1> 
     ) 
    } 
} 

正如你所看到的,承诺在被调用6秒后调用该决定。

还有一个名为“List”的组件负责在屏幕上显示这些项目。 “列表”是“项目”组件的父项。

class List extends React.Component{ 
    constructor(props){ 
     super(props) 
     this.state = { 
      items : [1,2,3] 
     } 

     this.handleRemove = this.handleRemove.bind(this) 
    } 

    handleRemove(id){ 
     this.setState((prevState, props) => ({ 
      items : prevState.items.filter((cId) => cId != id) 
     })); 
    } 

    render(){ 
     return (
      <div> 
      {this.state.items.map((item) => (
       <Item key={item} id={item} remove={this.handleRemove} /> 
      )) 
      } 
      </div> 
     ) 
    } 
} 

ReactDOM.render(<List />,root) 

在上面的例子中,它显示了屏幕上的三个项目。

enter image description here

如果删除任何这些组件的,componentWillUnmount()被调用,但也运行已在移除的组件创建的承诺。

例如,即使我删除第二个项目,我也可以看到第二个项目的承诺正在运行。

unmounted 
PROMISE COMPLETED 1 
PROMISE COMPLETED 2 
PROMISE COMPLETED 3 

我不得不取消组件卸载时的承诺。

+0

我想我们无法确认这个答案:https://stackoverflow.com/questions/30233302/promise-is-it -possible-to-force-cancel-a-promise,也请检查:https://esdiscuss.org/topic/cancellation-architectural-observations –

+0

你是否试图在'this.prom'处调用'Promise'构造函数一次? – guest271314

+1

不知道我完全理解这个问题,但[这个小提琴](https://jsfiddle.net/5Lrw2jqq/)有帮助吗?第8和28行是要看的 –

回答

-1

你可以做很多事情。最简单的是reject承诺:

this.prom = new Promise((resolve, reject) => { 
    this.rejectProm = reject; 
    ... 
}); 

然后

componentWillUnmount(){ 
    if (this.rejectProm) { 
     this.rejectProm(); 
     this.rejectProm = nil; 
    } 

    console.log("unmounted") 
}