useDebounceEffect 简介
在 React 项目里,useEffect 的使用频率很高,但频繁触发的副作用往往让人头疼。ahooks 提供的 useDebounceEffect 就是专门解决这个问题的——它是 useEffect 的防抖版本,当依赖项变化太快时,能优雅地控制 effect 的执行节奏,避免不必要的性能开销。
在项目中的具体应用
来看一个实际场景:问卷编辑器的自动保存功能。传统做法是用定时器定期保存,但更好的方案是「用户停止操作后再保存」。下面这段代码就实现了这个逻辑:
// 自定保存(不是定期保存,不是定时器)
useDebounceEffect(
() => {
sa ve()
},
[componentList, pageInfo],
{
wait: 1000,
}
)
参数说明
这个 hook 接收三个参数,每个都指向明确:
- 第一个参数(函数):要执行的副作用函数,也就是保存操作本身。
- 第二个参数(依赖数组):监听 componentList(组件列表)和 pageInfo(页面信息)的变化,只要任意一项变了,就会触发防抖逻辑。
- 第三个参数(配置对象):设置防抖等待时间,这里是 1000 毫秒,即 1 秒。
实际应用场景举例
假设用户正在编辑一份问卷,时间线可能是这样的:
- 0ms:用户修改了标题,pageInfo 发生变化,触发 useDebounceEffect。
- 500ms:用户又添加了一个组件,componentList 发生变化,重新开始计时。
- 800ms:用户修改了某个组件的属性,componentList 再次变化,再次重新计时。
- 1800ms:用户停止操作,在这 1 秒内没有新的变化。
- 此时才真正执行保存操作。
简单说,就是用户每次操作都会「重置计时器」,只有连续 1 秒没有新操作,才会触发保存。这比定时器更智能——不会在用户编辑过程中频繁打断,也不会在用户离开后迟迟不保存。
工作原理
整个流程可以拆解为三个步骤:
- 监听变化:hook 持续监听 componentList 和 pageInfo 的变动。
- 触发时机:当用户编辑导致依赖项变化时,启动防抖计时。
- 防抖处理:如果变化后 1 秒内没有新变化,才执行保存;如果期间又有变化,则重新计时,之前的保存操作自动取消。
这个过程看似简单,但背后涉及「取消上一次的定时器并重新设置」的机制,只是用 ahooks 封装后,开发者只需一行配置就能搞定。
优势
相比普通的 useEffect,useDebounceEffect 在自动保存场景中优势明显:
说白了,就是让保存操作更「聪明」——只在真正需要的时候才执行,而不是用户每点一下鼠标就发一次请求。
与其他类似 hook 的区别
在自动保存场景中,选择防抖而非节流是有原因的。防抖更关注「操作结束后再执行」,而节流是「固定间隔执行」。举个例子:
- useEffect:每次依赖变化都立即执行,相当于用户每改一个字符就保存一次,效率极低。
- useDebounceEffect:防抖执行,等待用户连续操作完后再保存,适合「保存最终结果」的场景。
- useThrottleEffect:节流执行,每隔一段时间执行一次,适合「需要持续更新但频率不能太高」的场景,比如滚动位置记录。
对于问卷编辑器的自动保存,显然防抖更符合直觉——用户完成一系列修改后,一次性保存所有改动,而不是每过几秒就强行保存一次。