score:1

Accepted answer

Technically you cannot cancel or abort a promise because the web browser does not expose any method for doing that.

What you can do instead is to just ignore the promise if the user navigated to another page. There are two methods to do that:

Using Redux, Thunk, and a promise middleware

You should not store your application state in your component state. By using Redux the application state will be shared amongst all components. Then you use redux-promise-middleware in combination with Thunk middleware to handle async actions in Redux.

Simply, in your action you can do something like this:

case 'LOAD_ORDERS_SUCCESS':
  if state.location != 'orders' { return }

  // store the data in the application state

Using RxJS and observables

Observables is an alternative way to Promises.

There is a library called redux-observable and a video from Netflix that explain how Observable can be used exactly for this very reason. Check out this recipe in their docs:

const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      ajax.getJSON(`/api/users/${action.payload}`)
        .map(fetchUserFulfilled)
        .takeUntil(action$.ofType(FETCH_USER_CANCELLED))
    );

score:2

Just think of componentWillUnmount as an opportunity function. It is your opportunity to do as the docs say, perform any additional clean up that React won't do on its own.

As far as XHR requests go, you would need to have a Promise library that supports cancelling the promise. If the library you use does support that then in the componentWillUnmount you would just make sure you have access to all Promises and cancel each one.

As far as canceling anything else, you just need to use whatever functions are provided for you to cancel whatever it is you want to cancel. If their is a function to cancel it then use the nature of componentWillUnmount to do so if you need it to be cancelled if the component is being unmounted.

As an example of how we use it where I'm at: If a component is going to make requests, we set a property on the component that is an array and holds all the requests. we would call this this.statePromises. Whenever we make a request/Promise we would push that Promise into the this.statePromises. In the componentWillUnmount we have the following

componentWillUnmount() {
  this.statePromises.forEach(p => p.cancel());
 }

p being a promise. This only works because of the library, bluebird, that we use for our promises. But that should give you an idea of how you could use componentWillUnmount to do any additional clean up.


Related Query

More Query from same tag