React中的useDebounceEffect用法举例
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">useDebounceEffect 简介</a></li><li><a href="#_label1">在项目中的具体应用</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">参数说明</a></li></ul><li><a href="#_label2">实际应用场景举例</a></li><ul class="second_class_ul"></ul><li><a href="#_label3">工作原理</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">优势</a></li><ul class="second_class_ul"></ul><li><a href="#_label5">与其他类似 hook 的区别</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>useDebounceEffect 简介</h2><p>useDebounceEffect 是 ahooks 库提供的一个自定义 hook,它是 useEffect 的防抖版本。当依赖项频繁变化时,它可以控制 effect 函数的执行频率,避免过于频繁的执行。</p>
<p class="maodian"><a name="_label1"></a></p><h2>在项目中的具体应用</h2>
<div class="jb51code"><pre class="brush:js;">// 自定保存(不是定期保存,不是定时器)
useDebounceEffect(
() => {
save()
},
,
{
wait: 1000,
}
)</pre></div>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>参数说明</h3>
<p class="maodian"><a name="_label2"></a></p><h2>实际应用场景举例</h2>
<p>假设用户在编辑问卷时:</p>
<p>1. <strong>0ms</strong>:用户修改了标题,pageInfo 发生变化,触发 useDebounceEffect</p>
<p><strong>2.500ms</strong>:用户又添加了一个组件,componentList 发生变化,重新开始计时</p>
<p><strong>3.800ms</strong>:用户修改了某个组件的属性,componentList 再次发生变化,再次重新计时4.<strong>1800ms</strong>:用户停止操作,在这 1 秒内没有新的变化</p>
<p>5.<strong>此时才真正执行保存操作</strong></p>
<p><strong>第一个参数(函数)</strong>:</p>
<div class="jb51code"><pre class="brush:js;">() => {
save()
}</pre></div>
<p>这是要执行的副作用函数,也就是自动保存操作。</p>
<p><strong>第二个参数(依赖数组)</strong>:</p>
<div class="jb51code"><pre class="brush:js;"></pre></div>
<p>这是依赖项数组,当其中任意一项发生变化时,会触发 effect。</p>
<p><strong>第三个参数(配置对象)</strong>:</p>
<div class="jb51code"><pre class="brush:js;">{
wait: 1000,
}</pre></div>
<p>配置防抖的等待时间,这里是 1000 毫秒(1 秒)。</p>
<p class="maodian"><a name="_label3"></a></p><h2>工作原理</h2>
<ul><li>这个自动保存功能的工作流程如下:<ul><li><strong>监听变化</strong>:hook 监听 componentList(组件列表)和 pageInfo(页面信息)的变化</li><li><strong>触发时机</strong>:当用户编辑问卷,导致组件列表或页面信息发生变化时</li><li><strong>防抖处理</strong>:</li></ul></li><li>如果变化发生后 1 秒内没有新的变化,才执行保存操作</li><li>如果在 1 秒内又有新的变化,会重新计时,之前的保存操作会被取消<ul><li><strong>执行保存</strong>:调用 save() 函数执行保存操作</li></ul></li></ul>
<p class="maodian"><a name="_label4"></a></p><h2>优势</h2>
<p>使用 useDebounceEffect 相比普通的 useEffect 有以下优势:</p>
<p><strong>减少不必要的请求</strong>:避免用户快速操作时频繁发送保存请求 <strong>节省服务器资源</strong>:降低服务器压力,减少数据库写入次数 <strong>提升用户体验</strong>:避免页面因为频繁保存而出现卡顿 <strong>网络优化</strong>:减少网络请求次数,节省带宽</p>
<p class="maodian"><a name="_label5"></a></p><h2>与其他类似 hook 的区别</h2>
<p>在自动保存场景中,使用防抖比节流更合适,因为我们希望在用户完成一系列操作后再保存,而不是每隔固定时间保存一次。</p>
<ol><li><strong>useEffect</strong>:每次依赖变化都立即执行</li><li><strong>useDebounceEffect</strong>:防抖执行,等待一段时间内不再变化才执行</li><li><strong>useThrottleEffect</strong>:节流执行,每隔一段时间执行一次</li></ol> 顶一下!正好最近在做问卷系统,这个自动保存功能正是我需要的,感谢分享!
补充一点:
除了 ahooks 的 useDebounceEffect,如果项目不想引入整个 ahooks 库,其实也可以自己手写一个简单的版本:
import { useEffect, useRef } from 'react';
function useDebounceEffect(effect, deps, options = { wait: 300 }) {
const effectRef = useRef();
const timeoutRef = useRef();
// 保存最新的 effect 函数
effectRef.current = effect;
useEffect(() => {
// 每次依赖变化时,清除之前的定时器
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
// 设置新的定时器
timeoutRef.current = setTimeout(() => {
effectRef.current();
}, options.wait);
// 清理函数
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, deps);
}
使用建议:
1. wait 时间不是固定的,要根据实际场景调整。问卷编辑可以设 1000ms,但搜索框建议设 300-500ms,否则用户会觉得响应慢
2. 注意清除定时器,避免内存泄漏
3. 如果 save 函数是异步的,最好加上 loading 状态,避免用户重复点击
大家还有什么其他好的实践吗?一起讨论一下~
頁:
[1]