react的hooks防抖和节流的具体实现
更新时间:2026年05月29日 09:45:01 作者:光影少年
本文主要介绍了react的hooks防抖和节流的具体实现,解释了为何需要特别处理闭包问题,并提供了具体实现方案,文章还强调了使用useRef保存最新函数的重要性,以及两种防抖节流方法的区别与应用场景,感兴趣的可以了解一下
一、先给面试官的“标准定义”(先声夺人)
防抖(debounce):在事件触发一段时间后才执行,期间再次触发会重新计时
节流(throttle):在固定时间内只执行一次
这一句一定要先说。
二、为什么在 React Hooks 里要“特别处理”?
问题本质:闭包 + 重新渲染
const fn = () => {
console.log(count)
}- 每次 render 都是新函数
- 定时器 / 事件里用的可能是旧状态
👉 普通 JS 防抖在 Hooks 里会失效或拿到旧值
三、Hooks 防抖(推荐实现)
1️⃣ 最稳方案:useRef + useCallback
function useDebounceFn(fn, delay = 300) {
const timer = useRef<number | null>(null)
const fnRef = useRef(fn)
// 始终指向最新 fn,解决闭包问题
fnRef.current = fn
const debounce = useCallback((...args) => {
if (timer.current) {
clearTimeout(timer.current)
}
timer.current = window.setTimeout(() => {
fnRef.current(...args)
}, delay)
}, [delay])
return debounce
}使用方式
const onSearch = useDebounceFn(value => {
fetchList(value)
}, 500)
<input onChange={e => onSearch(e.target.value)} />2️⃣ 面试官加分点
使用 useRef 保存最新函数,避免闭包导致状态不更新。
四、Hooks 节流(两种方式都要会)
方案一:时间戳节流(最稳定)
function useThrottleFn(fn, delay = 300) {
const lastTime = useRef(0)
const fnRef = useRef(fn)
fnRef.current = fn
return useCallback((...args) => {
const now = Date.now()
if (now - lastTime.current >= delay) {
lastTime.current = now
fnRef.current(...args)
}
}, [delay])
}方案二:定时器节流(常被追问)
function useThrottleFn(fn, delay = 300) {
const timer = useRef<number | null>(null)
const fnRef = useRef(fn)
fnRef.current = fn
return useCallback((...args) => {
if (timer.current) return
timer.current = window.setTimeout(() => {
fnRef.current(...args)
timer.current = null
}, delay)
}, [delay])
}两种节流的区别(面试官爱问)
| 方式 | 特点 |
|---|---|
| 时间戳 | 立即执行 |
| 定时器 | 延迟执行 |
五、为什么不用 lodash debounce?
可以用,但要说清楚限制
const debouncedFn = useMemo( () => debounce(fn, 300), [] )
❌ 问题:
- fn 变了,debounce 不更新
- 容易产生脏数据
正确用法
const fnRef = useRef(fn) fnRef.current = fn const debounced = useMemo( () => debounce((...args) => fnRef.current(...args), 300), [] )
六、Hooks 防抖节流常见坑(必背)
❌ 错误写法
const fn = debounce(() => {
setCount(count + 1)
}, 300)问题
- 每次 render 都创建新 debounce
- count 永远是旧值
✅ 正确认知
- 防抖节流函数要只创建一次
- 执行的函数要始终是最新的
七、什么时候用防抖?什么时候用节流?
防抖(Debounce)
- 搜索框
- 输入联想
- 表单校验
节流(Throttle)
- 滚动
- resize
- 拖拽
八、面试终极总结(一定要背)
React Hooks 下实现防抖节流,关键不是 setTimeout,而是用 useRef 解决闭包问题,保证函数引用稳定且状态最新。
到此这篇关于react的hooks防抖和节流的具体实现的文章就介绍到这了,更多相关react hooks防抖和节流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
相关文章
React中useEffect与生命周期钩子函数的对应关系说明
这篇文章主要介绍了React中useEffect与生命周期钩子函数的对应关系说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-09-09


最新评论