为啥在 componentDidMount 中取消异步/ajax 请求
Posted
技术标签:
【中文标题】为啥在 componentDidMount 中取消异步/ajax 请求【英文标题】:Why does an asynchronous/ajax request get cancelled in componentDidMount为什么在 componentDidMount 中取消异步/ajax 请求 【发布时间】:2018-12-19 00:24:52 【问题描述】:如果我的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 方法中取消所有订阅和异步任务。
如果我只是加载这个组件而我什至没有以任何方式卸载该组件,为什么它仍然被卸载。
我正在使用 react 路由器,每次使用我切换页面时都会收到 setState
错误。为什么我会收到此错误?为什么必须取消componentDidUnmount中的ajax调用的所有订阅?
【问题讨论】:
能否包含您的 React Router 代码以显示您如何使用此组件? 【参考方案1】:我是新来的反应,无论如何我会回答这个问题。这就是我认为正在发生的事情
您必须考虑两件事。第一个是 React,第二个是你在 componentDidMount
中发送的异步请求。
一旦当前组件被挂载,componentDidMount
就会被触发并发送异步请求。由于您使用的是axios
,它将返回一个承诺。现在承诺正在等待解决(或拒绝),一旦发生,您将更新状态。
现在,当您切换到新页面时,当前组件将被卸载。但请注意,promise 尚未解决,一旦解决,将调用 then
回调并更新组件的状态(已卸载)。这就是您收到错误的原因。
如果您在卸载时取消请求,则状态不会更新(因为我们不等待承诺解决)
【讨论】:
以上是关于为啥在 componentDidMount 中取消异步/ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章
为啥必须在 componentDidMount() 期间解析函数中的函数调用?