react-native ‘内存泄漏’警告 Can‘t perform a React state update on an unmounted component. 。。。

解决 react native ‘内存泄漏’警告

定时器引起的:

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.

例如:

在Home页面或者Hom页面组件设置了(setInterval)定时刷新的函数

Let timer = null

export default function Home ({ navigation}){

React.useEffect(

()=>{

timer &&clearInterval(timer)

timer = setInterval(()=>{

//函数体

},1000*60)

}

return ()=>{

timer &&clearInterval(timer)

}

),[ ]}

问题:当app退出,后台运行,或者home页面返回之前的页面(如果有),才会调用 return里面的清除定时器,

而从home页面跳转其他页面时(navigation.navigate(‘页面名称’)),此时并不会清除定时器,从而导致出现 ‘内存泄漏’ 警告。

解决方案:

  1. 监听 react navigation 的导航事件

‘focus‘ 获取焦点时开启定时器,

‘blur‘ 失去焦点时关闭定时器

调整后代码如下:

React.useEffect(

()=>{

navigation.addListener(‘focus’,()=>{

timer &&clearInterval(timer)

timer = setInterval(()=>{

//函数体

},1000*60)

})

navigation.addListener(‘blur’,()=>{

timer &&clearInterval(timer)

})

}

,[ ])

  1. react navigation hooks

import { useFocusEffect } from '@react-navigation/native';

与React.useEffect 差不多,return出来就行

useFocusEffect(

React.useCallback(()=>{

Let isOver = true

Const fetchRequest = async ()=>{

If(isOver){

timer&&clearInterval(timer)

timer = setInterval(()=>{

//函数体

},1000*60)

}

fetchRequest()

return ()=>{

timer&&clearInterval(timer) //清除

isOver = false  //跳转后不再设置定时器

}

}

},[ ])

)

网络请求引起的 ‘内存泄漏‘ 警告

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.

例如:

我们在home页列表上点击一条连接跳转到detail 页面,由于请求事件稍长(例如字段中含有base64的图片),未等到请求详情数据成功 我们直接返回到home页面,此时detail页面的请求并未结束,未报错的情况下,会稍后请求成功,更新详情页面的数据,但我们已经返回到home页面了,从而导致警告。

问题:如何终止网络请求,

解决方法:

封装fetch 请求 添加 AbortContorller()

Const request = (url,data)=>{

const abortController = new AbortController();

const signal = abortController.signal;

return {

    ready: fetch(url, {...initData, signal}).then(response => return response.json()),

    cancel: () => return abortController.abort(),

  };

};}

简单的使用:

const url = '接口地址';

const initData = {

  method: 'POST',

  body: JSON.stringify({key: value}),

  headers: {

    ' Authorization':token,

  },

  cache: 'no-cache',

  credentials: 'same-origin',

  mode: 'cors',

  redirect: 'follow',

  referrer: 'no-referrer',

};

const { ready,cancel } = request(url,initData)

请求数据

ready.then((res)=>{

console.log(res)

}).catch((err)=>{

Console.log(err)

})

‘blur 失去屏幕焦点时终止请求

navigation.addListener(‘blur’,()=>{

cancel()  //终止   err:Aborterror

})

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值