How to resolve the react, asynchronous setState warning?

all components will have ajax requests, and an error will be reported when switching.
check the cancellation request when uninstalling. I am almost done now. 100 api, must not be written 100 times?

Jul.14,2021

encapsulate a cancelable api class
1. Encapsulate all requests once according to the http method (get,post,put,delete)
2.

class ApiWithCancel {
  get = (url, params) => {
    //get, post put, del
    return this.makeCancelAble(get(url, params));
  }
  post = (url, params) => {
    return this.makeCancelAble(post(url, params));
  }
  put = (url, params) => {
    return this.makeCancelAble(put(url, params));
  }
  delete = (url, params) => {
    return this.makeCancelAble(fectchDel(url, params));
  }
  makeCancelAble = (promise) => {
    return new Promise(( resolve ) =>
      promise.then(val => !this.hasCanceled && resolve(val))
    );
  }
  cancel = () => {
    this.hasCanceled = true;
  }
}

3. In the constructor of the component used, new an instance of this class

this.api = new ApiWithCancel();

4. When using

const res = await this.api.get(url,params);

5. Cancel when the component is uninstalled

this.api.cancel()

Note: the code may not be used directly because it is encapsulated, but it means that it can be encapsulated into a class, with one new at a time. In addition, putting data in redux can also avoid this kind of alarm, but only if your data or actions are should be placed in redux .


does not use middleware such as redux-thunk or redux-saga? The call to ajax in the
component is usually triggered only in componentDidmount () , but it is also handled by redux.

your situation is that you must have called ajax in the pure function, which is rejected.


this react official has discussed it in great detail. I'll just give you a code.

if you want to know the whole story, stamp here https://reactjs.org/blog/2015.

.
const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val),
      error => hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

st cancelablePromise = makeCancelable(
  new Promise(r => component.setState({...}))
);

cancelablePromise
  .promise
  .then(() => console.log('resolved'))
  .catch((reason) => console.log('isCanceled', reason.isCanceled));

cancelablePromise.cancel(); // Cancel the promise

first of all, this problem is caused by ajax asynchronous callback setState, which occurs when the component is switched, and the component has been destroyed. Then calling setState will warn you.

all of the above methods are effective.
but not all of my current projects use redux to handle asynchrony, because the project situation is basically that an api will be used by a single component.

my solution is to cancel all outstanding requests last time when the route changes, because the problem is caused by the ajax asynchronous callback, so canceling the request will not go through the callback!
in this way, there is no need to introduce redux middleware to handle asynchronism, nor do you have to uninstall each component

.
Menu