1 组件卸载后要清楚定时任务

案列1 —发送短信限制倒计时

image.png

报错提示:无法对未装载的组件执行反应状态更新。这是一个不准的操作,但它表示应用程序内存泄漏。若要修复,请取消useffect清理函数中的所有订阅和异步任务

原因:

组件卸载了,但是仍处于渲染数据状态(如:setState,useState),一般写定时器时候会有出现。其他情况也会,只要组件卸载但仍在更新数据时机

关闭登录弹层后,sendMessage倒计时仍在执行
image.png
image.png

问题代码:

  1. timeRef.current = setInterval(()=> {
  2. setCountdown((countdown) => --countdown)
  3. console.log('倒计时ing');
  4. }, 1000)

解决:

使用useEffect模拟组件卸载后,清除可能存在的定时任务

  1. useEffect(() => {
  2. return () => {
  3. if(timeRef.current){
  4. clearInterval(timeRef.current)
  5. }
  6. }
  7. }, [])

案列2—轮询获取支付状态

现象:

一个扫码支付页面,因为无发获取用户支付操作,需要轮询调用接口获取支付状态,去完成后续操作。
image.png
但是当用户放弃支付,切换页面后,发现接口仍然在轮询
image.png

解决:

  1. useEffect(() => {
  2. return () => {
  3. if(timeRef.current){
  4. clearInterval(timeRef.current)
  5. }
  6. }
  7. }, [])

清除时机:

发生在更新完组件之后。
参考:
useEffect 完整指南 — Overreacted
image.png

案例3—第三方极验行为验证

登录注册弹层,为了安全因素,加入了第三方行为验证模块—极验
image.png
极验web SDK会做一系列初始化及事件监听及回调等等
image.png
如果关闭弹层,组件销毁后,但是极验实例仍然存在,可能导致回调异常,同时每次打开弹窗都会生成极验实例,可能到值内存问题。
所以关闭后需要清除实例

  1. // 组件卸载后,移除验证相关UI以及验证注册的事件监听器
  2. useEffect(() => {
  3. return () => {
  4. if(registerJiyanRef.current){
  5. registerJiyanRef.current.destroy()
  6. }
  7. if(loginJiyanRef.current){
  8. loginJiyanRef.current.destroy()
  9. }
  10. }
  11. }, [])