关于useEffect不得不注意的几点问题

本文探讨了在React中使用useEffect时需要注意的几个核心问题:副作用的概念及其在DOM构建后的执行时机,cleanup函数与组件卸载的区别,以及依赖项如何影响副作用的执行。强调了正确理解和使用依赖项、cleanup的重要性,以避免不必要的重渲染和逻辑错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引子:hooks如今使用的越来越频繁,但函数式编程和class组件的理解却不尽相同,导致转换过程中仍然照搬生命周期那一套,导致实现效果差强人意,虽然形似,却实际背道而驰!

如今,站在其他前辈的肩膀上,有幸能够理解useEffect的概念,着实让我感到庆幸,所以我想分享下关于useEffect要注意的点!

其一:基本概念之副作用

顾名思义,在完成某件事时附带执行的事,在useEffect的基本概念中,他表明了,在dom构建完成才执行,因为主要事是dom构建,所以其被称之为副作用,这里着重要注意的就是渲染时机了 =====> dom构建完成

其二:cleanup函数

其意为,副作用的清除,副作用会产生影响,因此我们需要消除它,从个人角度看,这个cleanup和生命周期的willUnmount真的太像了,可是实际上却不然,为什么?

我们都知道willUnmount表示的是组件卸载的生命周期,那cleanup呢?他只是副作用的清除操作罢了!副作用可以在组件挂载,重绘之后任意执行,那cleanup就永远只是清除上一个

副作用的函数罢了,那为什么cleanup又可以模拟willUnmount呢?那么就不得不说其三了!

其三:依赖项

副作用不可以每次渲染组件都执行,因此在每次渲染之后都需要判断其是否值得执行,由此出现依赖项,这有点类似与pureComponent(同样也是useMemo的基本)的理念,即

shallowEqual -> 浅比较,与第二点的关联处在于,当每次副作用执行时,若依赖项为空,代表着副作用只会在函数执行的第一次执行,在effect更新队列中,他在整个函数周期中基本上不会被干掉,只有当函数真正的卸载时,才会执行!

从上述而言,不知道有人发现没?

cleanup的真正用处是用于清除每一个上一次的effect的,他更应该用来针对每一次副作用做操作,而不完全是针对函数卸载来操作,

然而实际上在使用过程中,大多数人都喜欢添加空依赖项,或者就是单纯加一个cleanup函数,就以为能在函数卸载时执行了

由此,不正确的做法导致了与使用目的背离的理念,那么使用起来也就奇奇怪怪了!

那么,该如何正确使用?

我且说说依赖项,cleanup上述已讲:

依赖项的目的是什么?监听函数组件中的数据流变化,无论是props还是useState中的state变量,都应当被纳入到依赖项中,条件是:只要你的副作用会使用到这些变量,那么你就需要加入进去,别问为什么别人可以通过eslint-disable-line来取消依赖或者是使用ref来不触发重渲染,而我这里不这样做。

为什么?因为没必要,不符合涉及理念,当你需要时刻知道变量最新值的时候,为什么不让组件知道呢?就好比你需要食物来填饱肚子,但是服务员只端给你十分之一的食物,而你很明显没吃饱,但是服务员并不会继续端给你吃,为什么?因为你根本就没和人家说我还要再吃,那你自己饿肚子怪谁?

那么,请记住了,当你的副作用需要跟随数据流变化时,请记得一定要添加上去,并且切莫将数据流的变化写在副作用中,因为这时就是主作用了,而你加入到副作用中,能不进入死循环嘛?但从副作用这一层就能看出,他只是伴随主作用(组件重渲染)而进行的罢了,而你将副作用当做主作用来使用,那能怪谁呢?

在使用`useEffect`时,有几个注意事项需要注意: 1. 依赖项数组:`useEffect`接受一个依赖项数组作为第二个参数。这个数组用于指定在什么情况下应该执行`effect`函数。如果依赖项数组为空,`effect`函数只会在组件挂载和解挂时执行一次。如果依赖项数组包含了状态变量或其他引用类型的值,那么只有当这些依赖项发生变化时,`effect`函数才会重新执行。如果没有提供依赖项数组,`effect`函数将在每次组件重新渲染时都会执行。 2. 清除副作用:如果`effect`函数返回一个清除函数(cleanup function),则该清除函数将在组件解挂或下一次调用`effect`函数之前执行。这可以用于清理副作用,例如取消订阅、清除定时器等。确保在清除函数中正确地清理任何可能导致内存泄漏的资源。 3. 异步操作:`useEffect`函数内部可以包含异步操作,例如发送网络请求或访问浏览器的API。确保在异步操作中正确处理错误,并在组件解挂时取消未完成的异步操作,以免导致潜在的问题。 4. 优化性能:如果`useEffect`函数没有指定依赖项数组,它将在每次组件重新渲染时都会执行。这可能会导致性能问题,特别是在`effect`函数中包含了耗时的操作。为了避免不必要的执行,可以使用依赖项数组来指定需要监视的状态变量,并只在这些变量发生变化时执行`effect`函数。 5. 注意循环依赖:在某些情况下,`useEffect`可能会出现循环依赖的问题。例如,在`effect`函数中修改了某个状态变量,并将该状态变量添加到依赖项数组中,这可能导致无限循环。确保在使用依赖项数组时小心处理循环依赖的情况。 以上是使用`useEffect`时需要注意的一些事项,根据具体的使用场景和需求,可能还有其他需要留意的细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值