1 组件卸载后要清楚定时任务
案列1 —发送短信限制倒计时
报错提示:无法对未装载的组件执行反应状态更新。这是一个不准的操作,但它表示应用程序内存泄漏。若要修复,请取消useffect清理函数中的所有订阅和异步任务
原因:
组件卸载了,但是仍处于渲染数据状态(如:setState,useState),一般写定时器时候会有出现。其他情况也会,只要组件卸载但仍在更新数据时机
问题代码:
timeRef.current = setInterval(()=> {
setCountdown((countdown) => --countdown)
console.log('倒计时ing');
}, 1000)
解决:
使用useEffect模拟组件卸载后,清除可能存在的定时任务
useEffect(() => {
return () => {
if(timeRef.current){
clearInterval(timeRef.current)
}
}
}, [])
案列2—轮询获取支付状态
现象:
一个扫码支付页面,因为无发获取用户支付操作,需要轮询调用接口获取支付状态,去完成后续操作。
但是当用户放弃支付,切换页面后,发现接口仍然在轮询
解决:
useEffect(() => {
return () => {
if(timeRef.current){
clearInterval(timeRef.current)
}
}
}, [])
清除时机:
发生在更新完组件之后。
参考:
useEffect 完整指南 — Overreacted
案例3—第三方极验行为验证
登录注册弹层,为了安全因素,加入了第三方行为验证模块—极验
极验web SDK会做一系列初始化及事件监听及回调等等
如果关闭弹层,组件销毁后,但是极验实例仍然存在,可能导致回调异常,同时每次打开弹窗都会生成极验实例,可能到值内存问题。
所以关闭后需要清除实例
// 组件卸载后,移除验证相关UI以及验证注册的事件监听器
useEffect(() => {
return () => {
if(registerJiyanRef.current){
registerJiyanRef.current.destroy()
}
if(loginJiyanRef.current){
loginJiyanRef.current.destroy()
}
}
}, [])