在 ReactJS 中卸载组件时取消承诺 [英] Cancel a promise when a component is unmounted in ReactJS
问题描述
我有一个名为Item"的组件,它在挂载后创建并调用一个 promise.
class Item 扩展了 React.Component{构造函数(道具){超级(道具)this.onClick = this.onClick.bind(this)this.prom = new Promise((resolve, reject) => {setTimeout(() => resolve("承诺完成"+this.props.id),6000)})}componentDidMount(){this.prom.then((成功) => {控制台日志(成功)})}componentWillUnmount(){console.log("卸载")}点击(e){e.preventDefault()this.props.remove(this.props.id)}使成为(){返回 (<h1>项目 {this.props.id} - <a href="#" onClick={this.onClick}>Remove</a></h1>)}}
如您所见,promise 在调用后 6 秒调用了 resolve.
还有一个名为List"的组件负责在屏幕上显示这些项目.List"是Item"组件的父级.
class List 扩展 React.Component{构造函数(道具){超级(道具)this.state = {项目:[1,2,3]}this.handleRemove = this.handleRemove.bind(this)}处理删除(ID){this.setState((prevState, props) => ({项目:prevState.items.filter((cId) => cId != id)}));}使成为(){返回 (<div>{this.state.items.map((item) => (<Item key={item} id={item} remove={this.handleRemove}/>))}
)}}ReactDOM.render(<List/>,root)
在上面的例子中,它在屏幕上显示了三个项目.
如果我移除了这些组件中的任何一个,componentWillUnmount() 会被调用,但在移除的组件中创建的 promise 也会被运行.
例如,即使我删除了第二个项目,我也可以看到第二个项目的承诺正在运行.
已卸载承诺完成 1承诺完成 2承诺完成 3
我必须在卸载组件时取消承诺.
此变体 https://hshno.de/BJ46Xb_r7 似乎对我有用.我使用 mounted
实例变量创建了一个 HOC,并将所有异步组件包装在其中.
以下是我的代码大致的样子.
导出函数 makeMountAware(Component) {返回类 MountAwareComponent 扩展了 React.Component {安装 = 假;componentDidMount() {this.mounted = true;}componentWillUnmount() {this.mounted = false;}返回 (<组件安装 = {this.mounted}{...this.props}{...this.state}/>);}}类 AsyncComponent 扩展了 React.Component {componentDidMount() {fetchAsyncData().then(数据=> {this.props.mounted &&this.setState(prevState => ({...prevState,数据}));});}}导出默认 makeMountAware(AsyncComponent);
I've a component named "Item" which creates and calls a promise when it has been mounted.
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>
)
}
}
As you can see, the promise calls the resolve 6 seconds after it has been called.
There is another component named "List" that is responsible for showing those items on the screen. The "List" is the parent of the "Item" component.
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)
On the example above, it shows three Item on the screen.
If I remove any of those components, componentWillUnmount() is called but also the promise which has been created in the removed component is run.
For example, I can see the promise of the second item is run even if I remove the second item.
unmounted
PROMISE COMPLETED 1
PROMISE COMPLETED 2
PROMISE COMPLETED 3
I have to cancel the promise when a component is unmounted.
A variation of this https://hshno.de/BJ46Xb_r7 seemed to work for me.
I made an HOC with the mounted
instance variable and wrapped all async components in it.
Below is what my code roughly loks like.
export function makeMountAware(Component) {
return class MountAwareComponent extends React.Component {
mounted = false;
componentDidMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
return (
<Component
mounted = {this.mounted}
{...this.props}
{...this.state}
/>
);
}
}
class AsyncComponent extends React.Component {
componentDidMount() {
fetchAsyncData()
.then(data => {
this.props.mounted && this.setState(prevState => ({
...prevState,
data
}));
});
}
}
export default makeMountAware(AsyncComponent);
这篇关于在 ReactJS 中卸载组件时取消承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!