reactjs - 在 ReactJS 中卸载组件时取消 promise

标签 reactjs promise cancellation

我有一个名为“Item”的组件,它在安装后创建并调用 promise 。

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

如您所见,promise 在调用解析后 6 秒调用它。

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

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(),但也会运行在删除的组件中创建的 Promise。

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

unmounted 
PROMISE COMPLETED 1 
PROMISE COMPLETED 2 
PROMISE COMPLETED 3

卸载组件时我必须取消 promise 。

最佳答案

https://hshno.de/BJ46Xb_r7 的变体似乎对我有用。 我使用 mounted 实例变量创建了一个 HOC,并将所有异步组件包装在其中。

下面是我的代码大致的样子。

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 - 在 ReactJS 中卸载组件时取消 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44457788/

相关文章:

reactjs - 在 Gatsby 上,如何使用 prop 进行 GraphQL 查询?

css - Nextjs - 使用 css 模块设计嵌套元素

javascript - 在顶部滚动表格以添加新行

javascript - Bluebird promise 多个参数

javascript - Async/await - 等待函数和非等待函数的组合

javascript - 取消链接中 onClick 触发的 javascript 函数

javascript - 预期是赋值或函数调用,但看到的是三元表达式

angularjs - angular 然后从服务中捕获成功错误

ios - id 标识符 swift

c# - 发生类型为 'System.OperationCanceledException' 的异常