【React】useEffect缺少依赖警告

代码:

useEffect(() => {
  // ... 省略无关代码
  setFriends([msg, ...friends]);
}, [])

本意是获取到msg数据后,利用原有的friends,更新出现在的friends数据。

然后就报警告:

React Hook useEffect has a missing dependency: 'friends'. 
Either include it or remove the dependency array. 
You can also do a functional update 'setFriends(f => ...)' 
if you only need 'friends' in the 'setFriends' call  react-hooks/exhaustive-deps

原因大致是在useEffect中引入了friends这个状态数据,让friends变成了依赖数据。

这样可能会导致循环渲染的问题。就是friends变化了,然后去通过setFriends方法

去更新了friends,这让friends又发生了变化,于是继续去调用setFriends去更新friends

此时,如果不想让friends作为依赖项,就用函数的方式去删除friends这个外部依赖,

代码改为这样:

useEffect(() => {
  // ... 省略无关代码
  setFriends(friends => [msg, ...friends]);
}, [])

问题解决。

### 使用 `useEffect` 处理引用类型的依赖项 当在 React 的 `useEffect` 中遇到引用类型作为依赖项时,可能会因为对象或数组的浅比较特性而导致不必要的重新渲染。为了有效管理这种情况并优化性能,可以采用几种最佳实践方法。 #### 方法一:使用 `useMemo` 或者 `useCallback` 通过 `useMemo` 可以确保只有当其依赖项发生变化时才会计算新的值,从而保持引用的一致性。对于函数型依赖,则可利用 `useCallback` 来缓存函数实例[^2]。 ```javascript import React, { useState, useEffect, useMemo } from 'react'; function MyComponent() { const [count, setCount] = useState(0); // 创建一个复杂的对象,并仅在其内部属性改变时更新该对象 const complexObject = useMemo(() => ({ value: count }), [count]); useEffect(() => { console.log('Complex object changed:', complexObject); }, [complexObject]); // 将复杂对象设为依赖 return ( <div> Count: {count} <button onClick={() => setCount(prev => prev + 1)}>Increment</button> </div> ); } ``` #### 方法二:深比较库的应用 如果项目中频繁涉及深层嵌套的对象或数组对比,考虑引入专门用于深度相等检测的第三方工具包如 `lodash.isEqual` 或其他类似的实用程序来代替默认的行为[^3]。 ```javascript import isEqual from 'lodash/isEqual'; // ...其余代码省略... const shouldUpdateRef = useRef(false); useEffect(() => { if (!isEqual(complexObject.current, previousValue)) { // 执行副作用逻辑... shouldUpdateRef.current = true; } }, [complexObject]); ``` #### 方法三:自定义 Hook 实现记忆化功能 创建自己的 Hook 来封装特定业务场景下的需求,比如只关注某些字段的变化而不关心整个结构体是否变动。这种方式提高了灵活性和复用度。 ```javascript function useDeepCompareMemo(value, deps) { const ref = useRef(); if (ref.current === undefined || !shallowEquals(ref.current.deps, deps)) { ref.current = { value, deps }; } return ref.current.value; } // 浅层等于判断辅助函数 function shallowEquals(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; ++i) if (!Object.is(a[i], b[i])) return false; return true; } ``` 以上策略能够帮助开发者更好地控制 `useEffect` 对于引用类型依赖项的影响范围,在不影响应用正常运行的前提下减少不必要开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值