请教一个 react hook 的问题

282 天前
 Asuler

关于 react 的 useEffect ,如果我要监听一个值,并且在值变化的时候做一些函数调用

  useEffect(()=>{
    if(type === aaa){
      aHandle();
    }else if(type === bbb){
      bHandle();
    }
  }, [type])

那我就需要把 aHandle 和 bHandle 放入依赖项中,否则 eslint 或者 sonarlint 会报警告

  useEffect(()=>{
    if(type === aaa){
      aHandle();
    }else if(type === bbb){
      bHandle();
    }
  }, [type, aHandle, bHandle])

那这样岂不是每次 render ,都会重新生成新的 ahandle 和 bHandle ,每次都会触发 useEffect 吗?

我知道有 useCallback 和 useRef 可以解决函数在每次 render 都重新生成的问题,但问题是假如我在 aHandle 里去调接口,也要获取很多放在 state 中的值作为参数,那么 useCallback 还得把那些值全部放在 useCallback 的依赖项里,搞得越来越复杂了。

难道只能用 useRef 或者基于 useRef+useCallback 封装的一些 hook ,把每个 aHandle 或者 bHandle 给套上吗。

有没有更优雅一点的写法,我想要有一个 useXXXEffect,可以只监听一个 type ,在这里面获取到的其他值都是最新的,不再额外需要传入 aHandle 或者 bHandle 。

有没有这样的 hook 或者封装成这种效果的 hook

3169 次点击
所在节点    React
53 条回复
Asuler
281 天前
@w4ngzhen eslint 或者 sonarlint 警告就是说你没把 aHandle 和 bHandle 加到依赖项里,他们的特殊之处就是里面包含了一些异步的复杂逻辑,需要每次调用时都取到外部最新的值
Asuler
281 天前
统一回复下:eslint 和 sonarlint 不是我说禁用就能禁用的,公司私有化部署了代码扫描平台,会用这些扫描代码,作为员工绩效的一部分,我实属无奈呀,非常难受,如果是自己的项目,那我就直接不管了,害
Asuler
281 天前
所以说,useEffect 的用法,我其实理解错了,不应该这么用对么
Asuler
281 天前
再统一回复下:未出世的 useEvent ,useRef ,useMemoizedFn 之类的,本质上都要对那些 aHandle ,bHandle 套上,但是
1. 我需要给每个 handle 函数都给套上
2. 如果有些函数本身已经套了某种 hook 的,我难道还要再套一层?比如 useDebounceFn ,useThrottleFn ,已经套过一层了,难道要再套一层,我感觉不太优雅了
rocmax
281 天前
是不是把 vue 里用 watch 的习惯带来了?
type 在哪里变的就在哪里挂处理函数,useeffect 不是干这个的
lee88688
281 天前
闭包问题,在 react 里面没有太好的解决方案,op 说的是否还要再往上套的问题是肯定的,如果想要保持引用稳定就是要付出这个代价,这也就是 react 目前的问题。
vue 或者 solidjs 这些没有这个问题是因为他们所有的数据外面都有一层壳,vue 的 val.value ,solidjs 的 value(),都是帮你在外面加了一层,当然渲染机制也不同,所以加壳就加吧。
zbowen66
281 天前
@rocmax #45 别洗了,缺点就是缺点
dudubaba
281 天前
这种感觉就是 eslint 的锅, 这种场景还是很多的,因为 useEffect 不能直接用 async ,所以函数定义在 useEffect 里又不能共用,抽出来又出现你这种依赖报错问题,但是实际上不加函数依赖是正常的,用这种依赖问题又一大堆冗余代码。如果全局 eslint 改不掉建议用 eslint-disable-next-line 这种禁用掉。
rocmax
281 天前
@zbowen66 vue boy 这就破防了?
vue 里面不是一样不推荐滥用 watch 吗?到处 watch 的屎山我是见过的,哪里改变状态在哪里处理 state 不很正常吗?
react 手动依赖收集是比较麻烦,但这跟不该用 useeffect 监听状态修改有一毛钱关系吗?
zbowen66
280 天前
@rocmax #49 哈哈,说点 react 的缺点就被喷是 vue boy ,祝你生活愉快😁,告辞
jjwjiang
279 天前
@w4ngzhen 确实是这样,但是如果在 function 里有闭包那就是另一回事了。所以我觉得 eslint 这规则大部分时候是没用的,这规则最终导致的结果就是需要 memo 一大堆东西
HTML001
276 天前
四天过去了,OP 最终选择什么方案?
Asuler
276 天前
@HTML001 hook 往上套呗,代码都写了那么多了,不可能重构的,只要没出线上问题就不重构

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1028021

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX