解决 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(‘页面名称’)),此时并不会清除定时器,从而导致出现 ‘内存泄漏’ 警告。
解决方案:
- 监听 react navigation 的导航事件
‘focus‘ 获取焦点时开启定时器,
‘blur‘ 失去焦点时关闭定时器
调整后代码如下:
React.useEffect(
()=>{
navigation.addListener(‘focus’,()=>{
timer &&clearInterval(timer)
timer = setInterval(()=>{
//函数体
},1000*60)
})
navigation.addListener(‘blur’,()=>{
timer &&clearInterval(timer)
})
}
,[ ])
- 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
})