Tuomas Toivonen
Tuomas Toivonen

Reputation: 23472

How to to cancel pending asynchronous actions in React/Redux

Consider the following situation:

When user navigates to page, two asynchronous Redux actions are dispatched to fetch two sets of related data parallel. If either of these fetches fails, it will be detected by the component, which will render error component on next cycle, which in turn dispatches clearState action when mounting.

However, the other action is still to be resolved/rejected and will spoil the clean state. Objective is to interrupt this (and preferably many other) pending asynchronous actions, when clearState action creator is called. AFAIK, pending promise should either way resolve/response, no matter what.

First thing to come in my mind is to introduce INTERRUPTED flag to each reducer, but I can't wrap my head around how to use it to make following SUCCESS/ERROR action not to affect / return the default state.

How to do this, keeping the complexity at minimum?

Upvotes: 3

Views: 11473

Answers (2)

Sumit Gupta
Sumit Gupta

Reputation: 67

I was recently faced with the same problem, in which I had to cancel pending or stale async redux actions. I solved it by creating a cancel redux actions middleware.

In redux we have the concepts of middlewares. So when you are sending the request it will go through a list of middlewares. Once the api responds back its response will pass through a number of middlewares before it reaches redux store and eventually your UI.

Now suppose we have written a cancel middleware. The api request will go through this middleware when it being initiated and the api response will also go through this middleware when the api responds back.

Each api request in redux is associated with an action, each action has a type and payload.

Write a middleware, which whenever an api request is done stores the action type associated. Along with it, it stores a flag which states whether to discard this action. If an action of similar type is fired again, make this flag true which says discard this action. When the api response comes for the previous action since the discard flag for this api request has been set to true, send null as response from the middleware.

Look at this blog for detailed information about this approach. https://tech.treebo.com/redux-middlewares-an-approach-to-cancel-redux-actions-7e08b51b83ce

Upvotes: 1

Mohamed Ramrami
Mohamed Ramrami

Reputation: 12691

I had a similar problem, I'm using jquery for making ajax request and redux-thunk middleware.

The solution is to make your action creators return the promise, this promise will be returned by the dispatch function, then you'll be able to abort it.

In my action creator I have something like this :

function doSomething() {
  return (dispatch) => {
    return $.ajax(...).done(...).fail(...);
  }
}

Then in my component I have :

  componentDidMount(){
    this.myPromise = this.props.dispatch(doSomething());
  }

  somefnct() {
    this.myPromise.abort();
  }

Also have a look at this comment by Dan Abramov.

Upvotes: 1

Related Questions