当前位置: 首页 > news >正文

Vue转React踩坑记录——useEffect组件卸载时使用useState定义的值返回undefined

bug背景:vue转react踩坑。在vue数据是响应式的,卸载时不会出现数据已经赋值但是卸载是undefined情况,除非手动更改为undefined。而在react流行的hooks写法,你要一直操作数据,react提供的useEffect方法的return 里其实就像vue的unMounted生命周期,一些组件卸载时的清理工作都写在retrun里。然而,在卸载的时候要清理的方法一直报undefined。

如何使用useEffect进行组件卸载? 

  1. 依赖变量:如果你想要在组件卸载时执行一些清理工作,那么你应该将需要监听的变量添加到依赖数组中。这样,当这些变量发生变化时,useEffect 会重新执行。

  2. 不需要依赖的卸载逻辑:如果你需要在组件卸载时执行一些清理工作,而这些工作不依赖于组件内部的状态或属性,那么你可以将一个空数组([])作为依赖数组传递给 useEffect。这样,无论组件何时卸载,清理工作都会执行。

以下是一个例子,展示了如何在组件卸载时执行清理工作,而不需要依赖任何变量:

useEffect(() => {// 清理函数return () => {console.log('组件即将卸载,执行清理工作');};
}, []); // 空依赖数组,表示副作用只在组件卸载时执行

在这个例子中,即使没有指定任何依赖变量,useEffect 的清理函数也将在组件卸载时执行。

总结来说,是否需要依赖其他变量取决于你的具体需求。如果你需要在组件卸载时执行一些清理工作,并且这些工作依赖于某些变量,那么你应该将这些变量添加到依赖数组中。如果你不需要依赖任何变量,或者清理工作不依赖于组件的状态,那么可以传递一个空数组。

bug复现

 代码类似如下,使用useState定义变量,卸载时不依赖variable,组件意外退出,手动退出,只要卸载了就执行一次。

const CustModal= (props: {...}) => {const { source} = props;const [variable,setVariable]= useState<string>();useEffect(()=>{...}
,[source])useEffect(() => {return ()=>{if(variable){//卸载时undefinedclear();}}}, []);
}const fun=()=>{//视图操作setVariable("更改");
}

bug产生原因 

这里在第二个useEffect写的卸载方法。而这个useEffect依赖的是空数组,这个useEffect里的内容只会执行一次,及return 外一次,return 里方法一次。因为我们的变量赋值不是在这个useEffect里写的,所以对于useEffect卸载的时候它拿到的是初始值variable,这里使用useState没有定义默认值,所以是undefined。如果这样写,你一定能明白什么意思

假设卸载前一定会执行setVariable给variable赋值,那么第二个useEffect卸载时拿到的variable是什么呢?

答案是“我是初始值”

为什么?还是useEffect不依赖任何变量的情况下,之后执行一次,可以理解为对于第二个useEffect来说它只知道variable初始化,对于后面发生了什么是不知道的。所以卸载的时候只拿到了定义的变量值

const CustModal= (props: {...}) => {const { source} = props;const [variable,setVariable]= useState<string>("我是初始值");useEffect(()=>{...}
,[source])useEffect(() => {console.log(variable);return ()=>{if(variable){//卸载时undefinedclear();}}}, []);
}
//假设卸载前一定会执行
const fun=()=>{//视图操作setVariable("更改");
}

bug解决 

后来使用了useRef去定义变量就能拿到卸载时的值了

const CustModal= (props: {...}) => {const { source} = props;//使用useRef定义变量const variable = useRef<string>();useEffect(()=>{variable.current = source;}
,[source])useEffect(() => {return ()=>{if(variable.current){clear();}}}, []);
}

为什么使用useRef定义变量不会销毁? 

在修复的代码里,使用 useRef 来管理 variable 的状态。useRef 返回的对象有一个 current 属性,用于存储引用。这个引用值在组件的整个生命周期中保持不变,直到组件被卸载。因此,即使在组件卸载时访问 variable.current,它仍然会保持最后的值,而不是 undefined

总结

如果想模拟vue组件卸载只执行一次的逻辑,useEffect里不依赖任何值;而且又想拿到在组件里被修改的数据,就用useRef去定义变量!!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 小琳Python课堂:Python性能测试利器:`timeit`和`memory_profiler`模块的使用与实践
  • Windows 10和11中检查打印文档历史记录的几种方法
  • 职场人,请珍惜每一次发言汇报机会!攻略如下
  • python操作kafka
  • k8s-pod 实战四 什么是 Kubernetes Pod?如何在生产环境中使用它?(学习专场,实战就看这一篇就够了)
  • 一文带你springai+ollama实现chat
  • 华为OD机试真题 - 跳马 - 广度优先搜索BFS(Python/JS/C/C++ 2024 D卷 200分)
  • 计算机网络 第1章
  • AI升降梯人数智能监测摄像头
  • VLM 系列——phi3.5-Vision——论文解读
  • Python Excel 操作全面总结
  • 气膜体育馆:学校体育设施的全新选择—轻空间
  • mac/windows 软件推荐
  • win11+vscode+Flutter 开发环境配置
  • Python OpenCV 入门指南
  • [数据结构]链表的实现在PHP中
  • Babel配置的不完全指南
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Fastjson的基本使用方法大全
  • HTTP中的ETag在移动客户端的应用
  • input实现文字超出省略号功能
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Python 反序列化安全问题(二)
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • SQLServer之创建显式事务
  • Zepto.js源码学习之二
  • 成为一名优秀的Developer的书单
  • 翻译:Hystrix - How To Use
  • 猴子数据域名防封接口降低小说被封的风险
  • 每天10道Java面试题,跟我走,offer有!
  • 如何利用MongoDB打造TOP榜小程序
  • 算法-图和图算法
  • 算法系列——算法入门之递归分而治之思想的实现
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 用Visual Studio开发以太坊智能合约
  • 原生 js 实现移动端 Touch 滑动反弹
  • ​zookeeper集群配置与启动
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (Java数据结构)ArrayList
  • (MATLAB)第五章-矩阵运算
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (回溯) LeetCode 78. 子集
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (十八)三元表达式和列表解析
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转)树状数组