V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
june4
V2EX  ›  React

时隔多年再次用 react,请问 ahooks 的 useMemoizedFn 和 react 内置的 useEffectEvent 有什么异同?

  •  
  •   june4 · 22 小时 15 分钟前 · 1036 次点击

    重新快速扫了一遍 react 的文档,发现文档里多了一个useEffectEvent的函数,在入门文档里还多次提到。 源码如下 https://github.com/sanity-io/use-effect-event/blob/main/src/useEffectEvent.ts

    这个貌似是 ahooks 的 useMemoizedFn 全方位弱化版。

    因为 useEffectEvent 文档里严格要求:

    • 只在 Effect 内部调用他们。
    • 永远不要把他们传给其他的组件或者 Hook 。

    就是说这个使用范围限得很死干不了 useCallback 的活,而 useMemoizedFn 可以完全替代 useCallback 和 useEffectEvent 。

    看了眼二者的源码,主要区别是 useEffectEvent 只有在 render 后才有值,所以不能马上用,这和 useCallback 不同。

    那问题来了,为什么 react 要出这个垃圾版 useEffectEvent/useCallback 而不是 ahooks 的终级版呢?应该是有我想不到的理由,或者我的理解有什么不对的地方?

    12 条回复    2025-09-09 13:48:24 +08:00
    twig
        1
    twig  
       20 小时 40 分钟前
    全然不懂耶,虽然我一直在用 React 。
    gfreezy
        2
    gfreezy  
       20 小时 36 分钟前
    https://github.com/alibaba/hooks/issues/728#issuecomment-2597359079

    useMemoizedFn 是本质上是违反 react hook rules 的。
    bzw875
        3
    bzw875  
       20 小时 24 分钟前
    我 react 的玩不明白,我不会在引入别的轮子的
    june4
        4
    june4  
    OP
       20 小时 8 分钟前
    @gfreezy 确实,不过似乎没副作用🐶
    另外 useEffectEvent 我也没想明白为什么它要限制只能在那个 effect 里用,看源码把它当回调到处传似乎也没问题啊,只要不在 render 阶段调用,这样可以在绝大部分情况下代替更不好用的 useCallback 。
    gfreezy
        5
    gfreezy  
       16 小时 47 分钟前 via iPhone
    开 react compiler 就不需要用 memo 了,这个才是大趋势
    xu33
        6
    xu33  
       6 小时 27 分钟前
    太新了,没用过
    june4
        7
    june4  
    OP
       5 小时 15 分钟前
    @gfreezy 这不是一回事,看教程中的用法,useEffectEvent 用于响应值变化的。
    比如 useEffect(() => { ... }, [query, ...otherDeps])
    如果需要只在 query 变的时候重新查询,但代码块有别的依赖,导致别的依赖变的时候也会重新查询怎么办?
    以前我都是手动判断和前值的变化,有点麻烦,现在有这个就不必这样了,直接用一个简单的 dep 列表就行。
    hwdq0012
        8
    hwdq0012  
       4 小时 25 分钟前
    useEffectEvent 可以做 onloaded 事件用, depe list 写[] 就是只在加载时执行一次,
    函数里 returng 一个函数, 卸载时执行一次,不写卸载逻辑也可以
    hwdq0012
        9
    hwdq0012  
       4 小时 22 分钟前
    @hwdq0012 #8 https://github.com/nocanstillbb/mutipleTurboModulesInApp/blob/63bc2553bde157e2b06bd0ff6e3b399d15565eb8/views/Minesweeper/index.tsx#L46 , 我的 react native c++ mvvm 库使用这个方法,安装时把 useState 的 set 函数存到 c++中,卸载时从 c++中清空,
    codehz
        10
    codehz  
       3 小时 52 分钟前
    其实那个“规则”是为了 react compiler 可以直接从 hook 定义里静态分析。。。你把 useEffectEvent 传递到别的地方的话,就不好静态分析了
    Orangeee
        11
    Orangeee  
       3 小时 48 分钟前
    useMemoizedFn 每次在 render 过程中 ref.current 替换最新函数; useEffectEvent 是在 render 完成后进行 ref.current 替换;在 concurrent 模式下可能会中途丢弃 render ,useMemoizedFn 这种 render 中替换调度器无法感知所以没法回滚,useEffectEvent 这种 render 完成后替换就不会有这个问题。限制在 useEffect 里使用能保证 UI 已经 commit ,再去更新逻辑,保持一致。官方方案也更利于 DevTools 调试
    june4
        12
    june4  
    OP
       1 小时 2 分钟前
    @Orangeee 嗯你这说法似乎有理,现在 useEffectEvent 写逻辑也基本够用了。useMemoizedFn 只是性能优化手法,不用也没啥。
    不过,即使中间丢掉了几次 render,那也会最终一致(指向最新数据)的吧?所以 usememoizedFn 我想应该也不大会出 bug
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5316 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 06:50 · PVG 14:50 · LAX 23:50 · JFK 02:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.