我在React应用程序中遇到内存泄漏错误。调用API时发生错误。我的应用程序渲染了3次,因为页眉和页脚先获得setState,然后使用setState获得todoList。
下面的控制台错误
警告:无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。 index.js:1446
我尝试了_.isMounted方法来解决该问题,并且也可以使用,但是解决方案是deprecated。
下面的isMounted方法代码...
_isMounted = false
componentDidMount() {
this._isMounted = true
API.getTodoList().then(data => {
if (this._isMounted) {
this.setState({ itemList: data.data.itemList });
}
})
}
componentWillUnmount() {
this._isMounted = false
}
后来我尝试使用makeCancelable方法修复内存泄漏。但是它并没有解决问题,并且出现了相同的内存泄漏错误,以及来自.catch()的另一个错误
API调用:
// makeCancelable fn is defined at start
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;
},
};
};
componentDidMount() {
console.log("didMount")
this.cancelRequest = makeCancelable(
axiosClient.get('/todoList')
.then((response) => {
this.setState({ itemList: response.data.data.itemList })
})
.catch(({ isCanceled, ...error }) => console.log('isCanceled', isCanceled))
)
}
componentWillUnmount() {
console.log("componentUnmount")
this.cancelRequest.cancel();
}
是否有其他方法可以解决内存泄漏错误,而无需使用_.isMounted方法。
我会很感激。
答案 0 :(得分:0)
该消息警告内存泄漏的可能性。虽然原始代码可能会导致内存泄漏,但这并没有说明一个,具体取决于执行请求的方式
makeCancelable
被滥用,因为不能撤销承诺,所以它不会导致包装的整个承诺链无法执行。
应该是:
this.cancelRequest = makeCancelable(
axiosClient.get('/todoList')
);
cancelRequest.promise
.then(...)
.catch(({ isCanceled, ...error }) => console.log('isCanceled', isCanceled))
因为Axios已经提供了cancellation,所以不需要这样做:
this.cancelRequest = axios.CancelToken.source();
axiosClient.get('/todoList', { cancel: this.cancelRequest.token })
.then(...)
.catch(error => console.log('isCanceled', axios.isCancel(error)))