index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. 多种方法解决该问题
在React开发中,我们可能经常会遇到这个一个警告:
我们不能在组件销毁后设置state,防止出现内存泄漏的情况:
关于react中切换路由时报以上错误,实际的原因是因为在组件挂载(mounted)之后进行了异步操作,比如ajax请求或者设置了定时器等,而你在callback中进行了setState操作。当你切换路由时,组件已经被卸载(unmounted)了,此时异步操作中callback还在执行,因此setState没有得到值。
解决的方式有两种:
一、在卸载的时候对所有的操作进行清除(例如:abort你的ajax请求或者清除定时器)
componentDidMount = () => { //1.ajax请求 $.ajax('你的请求',{}) .then(res => { this.setState({ aa:true }) }) .catch(err => {}) //2.定时器 timer = setTimeout(() => { //dosomething },1000) } componentWillUnMount = () => { //1.ajax请求 $.ajax.abort() //2.定时器 clearTimeout(timer) }
二、设置一个flag,当unmount的时候重置这个flag
componentDidMount = () => { this._isMounted = true; $.ajax('你的请求',{}) .then(res => { if(this._isMounted){ this.setState({ aa:true }) } }) .catch(err => {}) } componentWillUnMount = () => { this._isMounted = false; }
三、最简单的方式(万金油)
componentDidMount = () => { $.ajax('你的请求',{}) .then(res => { this.setState({ data: datas, }); }) .catch(error => { }); } componentWillUnmount = () => { this.setState = (state,callback)=>{ return; }; }
四、在组件已经卸载时return,不去设置state:使用react组件this里面的updater属性上的isMounted方法判断组件是否存在,如果不存在,就return,不再去设置setState。
if (this.updater.isMounted(this)) { this.setState({ dashBoardDate: otherDashBoardDate }) } else { return }
五、react Hooks 解决:
useEffect(() => { let isUnmounted = false const abortController = new window.AbortController request.get('xxxxxx').then((resp:any):any => { if(resp.code == 200 && !isUnmounted){
this.setState({
//....
})
}
}).finally(() => { }) return () => { isUnmounted = true abortController.abort }; },[]);