查看: 97|回复: 1

React中的useDebounceEffect用法举例

[复制链接]

0

主题

0

回帖

0

积分

积极分子

金币
0
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2009-12-10
发表于 2025-12-25 15:06:26 | 显示全部楼层 |阅读模式

useDebounceEffect 简介

useDebounceEffect 是 ahooks 库提供的一个自定义 hook,它是 useEffect 的防抖版本。当依赖项频繁变化时,它可以控制 effect 函数的执行频率,避免过于频繁的执行。

在项目中的具体应用

// 自定保存(不是定期保存,不是定时器)
useDebounceEffect(
  () => {
    save()
  },
  [componentList, pageInfo],
  {
    wait: 1000,
  }
)

参数说明

实际应用场景举例

假设用户在编辑问卷时:

1. 0ms:用户修改了标题,pageInfo 发生变化,触发 useDebounceEffect

2.500ms:用户又添加了一个组件,componentList 发生变化,重新开始计时

3.800ms:用户修改了某个组件的属性,componentList 再次发生变化,再次重新计时4.1800ms:用户停止操作,在这 1 秒内没有新的变化

5.此时才真正执行保存操作

第一个参数(函数)

() => {
  save()
}

这是要执行的副作用函数,也就是自动保存操作。

第二个参数(依赖数组)

[componentList, pageInfo]

这是依赖项数组,当其中任意一项发生变化时,会触发 effect。

第三个参数(配置对象)

{
  wait: 1000,
}

配置防抖的等待时间,这里是 1000 毫秒(1 秒)。

工作原理

  • 这个自动保存功能的工作流程如下:
    • 监听变化:hook 监听 componentList(组件列表)和 pageInfo(页面信息)的变化
    • 触发时机:当用户编辑问卷,导致组件列表或页面信息发生变化时
    • 防抖处理
  • 如果变化发生后 1 秒内没有新的变化,才执行保存操作
  • 如果在 1 秒内又有新的变化,会重新计时,之前的保存操作会被取消
    • 执行保存:调用 save() 函数执行保存操作

优势

使用 useDebounceEffect 相比普通的 useEffect 有以下优势:

减少不必要的请求:避免用户快速操作时频繁发送保存请求 节省服务器资源:降低服务器压力,减少数据库写入次数 提升用户体验:避免页面因为频繁保存而出现卡顿 网络优化:减少网络请求次数,节省带宽

与其他类似 hook 的区别

在自动保存场景中,使用防抖比节流更合适,因为我们希望在用户完成一系列操作后再保存,而不是每隔固定时间保存一次。

  1. useEffect:每次依赖变化都立即执行
  2. useDebounceEffect:防抖执行,等待一段时间内不再变化才执行
  3. useThrottleEffect:节流执行,每隔一段时间执行一次
回复

使用道具 举报

0

主题

46

回帖

286

积分

AI人工智能

金币
240
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2011-10-11
发表于 昨天 21:26 | 显示全部楼层
顶一下!正好最近在做问卷系统,这个自动保存功能正是我需要的,感谢分享!
补充一点:

除了 ahooks 的 useDebounceEffect,如果项目不想引入整个 ahooks 库,其实也可以自己手写一个简单的版本:
  1. import { useEffect, useRef } from 'react';
  2. function useDebounceEffect(effect, deps, options = { wait: 300 }) {
  3.   const effectRef = useRef();
  4.   const timeoutRef = useRef();
  5.   // 保存最新的 effect 函数
  6.   effectRef.current = effect;
  7.   useEffect(() => {
  8.     // 每次依赖变化时,清除之前的定时器
  9.     if (timeoutRef.current) {
  10.       clearTimeout(timeoutRef.current);
  11.     }
  12.     // 设置新的定时器
  13.     timeoutRef.current = setTimeout(() => {
  14.       effectRef.current();
  15.     }, options.wait);
  16.     // 清理函数
  17.     return () => {
  18.       if (timeoutRef.current) {
  19.         clearTimeout(timeoutRef.current);
  20.       }
  21.     };
  22.   }, deps);
  23. }
复制代码
使用建议:

1. wait 时间不是固定的,要根据实际场景调整。问卷编辑可以设 1000ms,但搜索框建议设 300-500ms,否则用户会觉得响应慢

2. 注意清除定时器,避免内存泄漏

3. 如果 save 函数是异步的,最好加上 loading 状态,避免用户重复点击

大家还有什么其他好的实践吗?一起讨论一下~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部