Cancel All Subscriptions and Asyncs in the componentWillUnmount Method, how?

前端 未结 3 1478
鱼传尺愫
鱼传尺愫 2020-12-09 14:58

I\'m getting an error message due to an async method issue. In my terminal I\'m seeing:

Warning: Can\'t call setState (or forceUpdate) on an unmounted compon         


        
相关标签:
3条回答
  • 2020-12-09 15:38

    From the React blog

    Just set a _isMounted property to true in componentDidMount and set it to false in componentWillUnmount, and use this variable to check your component’s status.

    It goes on to say that ideally, this would instead be fixed by using cancellable callbacks, although the first solution seems suitable here.

    What you definitely shouldn't do is use the isMounted() function, which may be deprecated.

    0 讨论(0)
  • 2020-12-09 15:40

    You can use isMounted React pattern to avoid memory leaks here.

    In your constructor:

    constructor(props) {
        super(props);
    
        this._isMounted = false;
    // rest of your code
    }
    
    componentDidMount() {
        this._isMounted = true;
        this._isMounted && this.getImage(this.props.item.image);
    

    }

    in your componentWillUnmount

    componentWillUnmount() {
       this._isMounted = false;
    }
    

    While in you getImage()

    async getImage(img) {
        let imgUri = await Amplify.Storage.get(img)
        let uri = await CacheManager.get(imgUri).getPath()
    
        this._isMounted && this.setState({
            image: { uri },
            ready: true
        })
    }
    

    A recommend approach to use Axios which is based cancellable promise pattern. So you can cancel any network call while unmounting the component with it's cancelToken subscription. Here is resource for Axios Cancellation

    0 讨论(0)
  • 2020-12-09 15:58

    You need to set this.mounted = false in componentWillUnmount() method and this.mounted = true in componentDidMount() method.

    The setState update is conditional based need to declare in componentDidMount() method.

    componentDidMount() {
            this.mounted = true;
            var myVar =  setInterval(() => {
                    let nextPercent = this.state.percentage+10;
                    if (nextPercent >= 100) {
                        clearInterval(myVar);
                    }
                    if(this.mounted) {
                        this.setState({ percentage: nextPercent });
                }
            }, 100);
    }
    
    componentWillUnmount(){
          this.mounted = false;
    }
    
    0 讨论(0)
提交回复
热议问题