如何重置Lodash Debounce状态,实现停止点击1秒后触发提示
解决Lodash Debounce的两个问题:重置状态与点击结束后触发
原代码问题分析
你的代码中,每次count更新时,useEffect都会创建一个全新的debounce函数实例并立即调用。这会导致:
- 持续点击按钮时,多个独立的防抖实例在同时计时,最终批量输出日志,无法实现“停止点击1秒后才触发”的需求;
- 无法对防抖状态进行重置,因为每次都是新的实例,没有统一的引用可以操作。
解决方案
1. 重置Lodash Debounce状态
Lodash的debounce函数返回的结果自带两个关键方法:
cancel():取消当前处于等待状态的防抖任务,重置计时状态,下次调用防抖函数会重新开始计时;flush():立即执行防抖函数,同时清除当前的等待状态。
只要持有防抖函数的实例引用,就能通过这两个方法重置或控制它的状态。
2. 实现停止点击1秒后输出提示
通过useRef保存防抖函数实例,确保组件生命周期内只有一个防抖实例,在点击事件中调用它来实现预期效果:
import React, { useState, useRef, useEffect } from "react"; import _debounce from "lodash/debounce"; import "./styles.css"; export default function App() { const [count, setCount] = useState(0); // 用useRef持久化防抖函数实例 const debouncedHandler = useRef(); // 仅在组件首次挂载时创建防抖函数 if (!debouncedHandler.current) { debouncedHandler.current = _debounce(() => { console.log("button clicks are over"); }, 1000); } const handleButtonClick = () => { setCount(prev => prev + 1); // 每次点击调用防抖函数,自动重置计时 debouncedHandler.current(); }; // 组件卸载时清理防抖任务,避免内存泄漏 useEffect(() => { return () => { debouncedHandler.current?.cancel(); }; }, []); return ( <div className="App"> <p>you clicked {count} </p> <button onClick={handleButtonClick}>Click on me</button> </div> ); }
代码说明:
- 使用
useRef保存防抖函数实例,避免每次组件渲染都创建新的debounce实例; - 按钮点击时调用防抖函数,每次调用都会重置1秒的计时——只有当用户停止点击超过1秒,防抖函数才会执行并输出提示;
- 组件卸载时调用
cancel(),清理未执行的防抖任务,防止内存泄漏; - 如果需要在某个场景下重置防抖状态(比如用户中途取消操作),直接调用
debouncedHandler.current.cancel()即可。
内容的提问来源于stack exchange,提问作者Виктория
相关产品推荐
相关产品推荐

