重新快速扫了一遍 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 20 小时 40 分钟前
全然不懂耶,虽然我一直在用 React 。
|
![]() |
2
gfreezy 20 小时 36 分钟前
https://github.com/alibaba/hooks/issues/728#issuecomment-2597359079
useMemoizedFn 是本质上是违反 react hook rules 的。 |
![]() |
3
bzw875 20 小时 24 分钟前
我 react 的玩不明白,我不会在引入别的轮子的
|
![]() |
4
june4 OP @gfreezy 确实,不过似乎没副作用🐶
另外 useEffectEvent 我也没想明白为什么它要限制只能在那个 effect 里用,看源码把它当回调到处传似乎也没问题啊,只要不在 render 阶段调用,这样可以在绝大部分情况下代替更不好用的 useCallback 。 |
![]() |
5
gfreezy 16 小时 47 分钟前 via iPhone
开 react compiler 就不需要用 memo 了,这个才是大趋势
|
![]() |
6
xu33 6 小时 27 分钟前
太新了,没用过
|
![]() |
7
june4 OP @gfreezy 这不是一回事,看教程中的用法,useEffectEvent 用于响应值变化的。
比如 useEffect(() => { ... }, [query, ...otherDeps]) 如果需要只在 query 变的时候重新查询,但代码块有别的依赖,导致别的依赖变的时候也会重新查询怎么办? 以前我都是手动判断和前值的变化,有点麻烦,现在有这个就不必这样了,直接用一个简单的 dep 列表就行。 |
8
hwdq0012 4 小时 25 分钟前
useEffectEvent 可以做 onloaded 事件用, depe list 写[] 就是只在加载时执行一次,
函数里 returng 一个函数, 卸载时执行一次,不写卸载逻辑也可以 |
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++中清空,
|
![]() |
10
codehz 3 小时 52 分钟前
其实那个“规则”是为了 react compiler 可以直接从 hook 定义里静态分析。。。你把 useEffectEvent 传递到别的地方的话,就不好静态分析了
|
11
Orangeee 3 小时 48 分钟前
useMemoizedFn 每次在 render 过程中 ref.current 替换最新函数; useEffectEvent 是在 render 完成后进行 ref.current 替换;在 concurrent 模式下可能会中途丢弃 render ,useMemoizedFn 这种 render 中替换调度器无法感知所以没法回滚,useEffectEvent 这种 render 完成后替换就不会有这个问题。限制在 useEffect 里使用能保证 UI 已经 commit ,再去更新逻辑,保持一致。官方方案也更利于 DevTools 调试
|