react报错:Can‘t perform a React state update on an unmounted component.

2022-08-09 11:25:18

问题描述:

项目中,在网络请求没有返回之前就跳转到另外的页面,结果发现控制台报错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. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
项目中的请求写法类似下面这样

useEffect(()=>{const reqData=async()=>{try{const res: any=awaitaxios('xxxxx');setData(res)}catch(err){
        console.log(err);}}reqData();},[]);

原因分析:

报错告诉我们无法对已卸载的组件执行状态更新,它表示应用程序中存在内存泄漏。
因为在请求还没返回之前,用户进行了页面跳转,跳转之后当前组件被卸载。而在卸载之后,请求返回,执行await之后的代码,对组件执行状态更新,可是此时组件已经被卸载,所以才会导致报错。


解决方案:

查看了react文档之后,知道可以通过effect 内部的局部变量来处理无序的响应:

useEffect(()=>{let ignore=false;const reqData=async()=>{try{const res: any=awaitaxios('xxxxx');if(!ignore){// 判断当前组件有没有被卸载setData(res)}}catch(err){
        console.log(err);}}reqData();return()=>{ ignore=true};},[]);

这样在组件卸载后就不会执行状态更新了


上面的方法适用于只有初始化时才会发起请求更新状态的组件。但是如果有的组件是在触发某些事件之后才发起请求更新状态的话,就需要换一个方式来防止内存泄露了。

可以通过useRef新建一个ref对象,用来记录当前组件有没有被卸载,在请求成功后,更新状态前判断一下,即可防止内存泄露。

constApp=()=>{const[data, setData]=useState([]);const isUnmounted=useRef(false);useEffect(()=>{return()=>{
      isUnmounted.current=true;}},[])const handleClick=async()=>{const res: any=awaitaxios('xxxx');if(!isUnmounted.current){// 判断当前组件有没有被卸载setData(res);}}return(<><button onClick={handleClick}>点击获取数据</button>...</>)}
  • 作者:残哥o
  • 原文链接:https://blog.csdn.net/ncgNCGg/article/details/122619905
    更新时间:2022-08-09 11:25:18