1

I navigate between two screen success but It always shows warning me below:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method

in Alert (at AwesomeAlert.js:7)

in AwesomeAlert (at LoadingDialog.js:7)

in LoadingDialog (at LoginScreen.js:180)

How to fix it?

Community
  • 1
  • 1
Vichit Pov
  • 83
  • 2
  • 6

2 Answers2

1

You can set a a boolean state flag on mount (isMounted or similar) and then set it to false in componentWillUnmount. Check this flag before calling the function(s) that are raising this warning.

Will Jenkins
  • 9,507
  • 1
  • 27
  • 46
  • While this works, [isMounted is an antipattern](https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html). Better to clean up tasks specifically and use AbortController – warrenbuffering Jun 12 '19 at 23:01
  • Point of order, `isMounted()` is an antipattern, using a property is a suggested migration path away from it: "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" – Will Jenkins Jun 13 '19 at 06:16
1

1) Make sure you have any event listeners, setTimeouts or setIntervals in componentDidMount and remove them in componentWillUnmount

Example for listeners, setTimeouts and setIntervals:

componentDidMount() {

  this.myTimer = setTimeout(() => {
    // someCode here
  }, 7000);

  AppState.addEventListener('change', this.handleAppStateChange);
}


componentWillUnmount() {

   AppState.removeEventListener('change', this.handleAppStateChange);
   clearTimeout(this.myTimer);

}

2) To cancel a fetch you have the following options:

Option A: Use AbortController

(In my opinion AbortController is much better than the old solution with isMounted variable)

AbortController example:

import "abortcontroller-polyfill"; // in RN 0.60+ this will probably not be needed anymore

class App extends React.Component {
    constructor() {
        const AbortController = window.AbortController;
        this.controller = new AbortController();
        this.signal = this.controller.signal;
    }
componentDidMount() {
    const url = "https://myurl.com";
    const signal = this.signal;

    fetch(url, { signal })
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => {
        // You can catch the error
        // thrown by the polyfill here.
        if (err.name == "AbortError") {
            console.log("Fetch Aborted");
        } else {
           //Catch other errors.
        }
    });
}
componentWillUnmount() {
    this.controller.abort();
}
/*--Rest of the code.--*/

}

Option B: Use Axios and trigger a cancellation in componentDidMount

https://github.com/axios/axios#cancellation

Sources:

AbortController code: https://github.com/facebook/react-native/issues/18115#issuecomment-420766665

How to cancel a fetch on componentWillUnmount

https://developer.mozilla.org/en-US/docs/Web/API/AbortController

Florin Dobre
  • 9,872
  • 3
  • 59
  • 93