重新快速扫了一遍 react 的文档,发现文档里多了一个useEffectEvent
的函数,在入门文档里还多次提到。 源码如下 https://github.com/sanity-io/use-effect-event/blob/main/src/useEffectEvent.ts
这个貌似是 ahooks 的 useMemoizedFn 全方位弱化版。
就是说这个使用范围限得很死干不了 useCallback 的活,而 useMemoizedFn 可以完全替代 useCallback 和 useEffectEvent 。
看了眼二者的源码,主要区别是 useEffectEvent 只有在 render 后才有值,所以不能马上用,这和 useCallback 不同。
那问题来了,为什么 react 要出这个垃圾版 useEffectEvent/useCallback 而不是 ahooks 的终级版呢?应该是有我想不到的理由,或者我的理解有什么不对的地方?
![]() | 1 twig 31 天前 全然不懂耶,虽然我一直在用 React 。 |
![]() | 2 gfreezy 31 天前 ![]() https://github.com/alibaba/hooks/issues/728#issuecomment-2597359079 useMemoizedFn 是本质上是违反 react hook rules 的。 |
![]() | 3 bzw875 31 天前 我 react 的玩不明白,我不会在引入别的轮子的 |
![]() | 4 june4 OP @gfreezy 确实,不过似乎没副作用 另外 useEffectEvent 我也没想明白为什么它要限制只能在那个 effect 里用,看源码把它当回调到处传似乎也没问题啊,只要不在 render 阶段调用,这样可以在绝大部分情况下代替更不好用的 useCallback 。 |
![]() | 5 gfreezy 30 天前 via iPhone 开 react compiler 就不需要用 memo 了,这个才是大趋势 |
![]() | 6 xu33 30 天前 太新了,没用过 |
![]() | 7 june4 OP @gfreezy 这不是一回事,看教程中的用法,useEffectEvent 用于响应值变化的。 比如 useEffect(() => { ... }, [query, ...otherDeps]) 如果需要只在 query 变的时候重新查询,但代码块有别的依赖,导致别的依赖变的时候也会重新查询怎么办? 以前我都是手动判断和前值的变化,有点麻烦,现在有这个就不必这样了,直接用一个简单的 dep 列表就行。 |
8 hwdq0012 30 天前 useEffectEvent 可以做 onloaded 事件用, depe list 写[] 就是只在加载时执行一次, 函数里 returng 一个函数, 卸载时执行一次,不写卸载逻辑也可以 |
9 hwdq0012 30 天前 @hwdq0012 #8 https://github.com/nocanstillbb/mutipleTurboModulesInApp/blob/63bc2553bde157e2b06bd0ff6e3b399d15565eb8/views/Minesweeper/index.tsx#L46 , 我的 react native c++ mvvm 库使用这个方法,安装时把 useState 的 set 函数存到 c++中,卸载时从 c++中清空, |
![]() | 10 codehz 30 天前 其实那个“规则”是为了 react compiler 可以直接从 hook 定义里静态分析。。。你把 useEffectEvent 传递到别的地方的话,就不好静态分析了 |
11 Orangeee 30 天前 useMemoizedFn 每次在 render 过程中 ref.current 替换最新函数; useEffectEvent 是在 render 完成后进行 ref.current 替换;在 concurrent 模式下可能会中途丢弃 render ,useMemoizedFn 这种 render 中替换调度器无法感知所以没法回滚,useEffectEvent 这种 render 完成后替换就不会有这个问题。限制在 useEffect 里使用能保证 UI 已经 commit ,再去更新逻辑,保持一致。官方方案也更利于 DevTools 调试 |