为什么异步/ ajax请求在componentDidMount中被取消

时间:2018-07-11 04:41:33

标签: ajax reactjs xmlhttprequest axios

因此,如果我在componentDidMount生命周期中拥有一个api

constructor() {
   this.source = axios.CancelToken.source();
}

componentDidMount() {
  axios.get('some-api-url', {
    cancelToken: this.source.token,
  });
  .then(res => {
     // set state here or do something based on response i get
  })
  .catch(error => {
    // handle error
  })
}

componentWillUnmount() {
  this.source.cancel('request cancelled');
}

回到我的问题,为什么我必须这样做,只是为了避免出现此错误;

  

警告:无法在已卸载的组件上调用setState(或forceUpdate)。这是空操作,但它表明应用程序中发生内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。

如果我只是加载了该组件,而我什至都没有卸载该组件,为什么仍然要卸载它。

我使用反应路由器,每次使用setState错误时切换页面。为什么会出现此错误?为什么我必须取消componentDidUnmount中对ajax调用的所有订阅?

1 个答案:

答案 0 :(得分:0)

我是新来的反应者,无论如何我都要回答。我认为这是正在发生的事情

您必须考虑两件事。第一个是React,第二个是您在componentDidMount内部发送的异步请求。

一旦安装了当前组件,就会触发componentDidMount并发送异步请求。由于您使用的是axios,它将返回一个Promise。现在,承诺正在等待解决(或拒绝),一旦发生,您将更新状态。

现在,当您切换到新页面时,当前组件将被卸载。但是请注意,promise尚未解决,一旦解决,将调用then回调,并更新组件的状态(已卸载)。这就是为什么您得到错误。 如果您在卸载时取消了请求,那么状态将不会更新(因为我们不在等待诺言解决)