news 2026/7/10 11:06:29

react的hooks防抖和节流是怎样做的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
react的hooks防抖和节流是怎样做的

一、先给面试官的“标准定义”(先声夺人)

防抖(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 解决闭包问题,保证函数引用稳定且状态最新。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 4:43:54

亲测有效!企业年会扫码投票小程序实战分享

技术痛点引入 公司企业年会大屏扫码实时节目投票小程序的高并发处理与用户体验优化是当前行业普遍面临的难题。 解决方案定位 熹乐大屏互动针对这一问题提供了专业解决方案。 技术详解 该系统采用分布式架构和负载均衡技术&#xff0c;通过智能调度算法实现高效的请求处理和…

作者头像 李华
网站建设 2026/7/1 20:44:03

基于YOLOv11的农作物病虫害检测识别系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于YOLOv11的农作物病虫害检测识别系统(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码 项目描述 本系统是一个完整的基于YOLOv11pytorchFlaskSpringBootVueMySQL的农作物病虫害检测识别系统。以下是主要功能的简单介绍&#…

作者头像 李华
网站建设 2026/7/1 6:52:40

python新能源汽车数据分析大屏可视化系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

python新能源汽车数据分析大屏可视化系统(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码爬虫可用 前后端分离 技术栈&#xff1a;Django、Mysql、DataV 介绍 Python开发的汽车数据分析大屏可视化系统&#xff0c;旨在帮助用户…

作者头像 李华
网站建设 2026/7/2 1:36:16

计算机毕设java新疆IP形象NFT藏品网站 基于SpringBoot的新疆文化IP数字藏品交易平台 “丝路映象“非遗数字资产发行与展示系统

计算机毕设java新疆IP形象NFT藏品网站w6q0g9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。在"东数西算"与"文化数字化"双重战略推动下&#xff0c;新疆丰…

作者头像 李华
网站建设 2026/7/2 1:36:20

GitHub 热榜项目 - 日榜(2026-02-08)

GitHub 热榜项目 - 日榜(2026-02-08) 生成于&#xff1a;2026-02-08 统计摘要 共发现热门项目&#xff1a; 12 个 榜单类型&#xff1a;日榜 本期热点趋势总结 本期GitHub热榜凸显AI驱动的实用开发工具成为核心趋势&#xff0c;开源社区正聚焦于提升开发效率与软件安全。O…

作者头像 李华
网站建设 2026/7/8 9:52:14

信创办公套件如何实现Word批注的完整Web转存?

企业级CMS编辑器增强功能实施方案 一、项目概述 作为安徽集团上市公司项目负责人&#xff0c;针对企业网站后台管理系统编辑器功能增强需求&#xff0c;我司计划开发一套支持多格式文档导入、微信公众号内容抓取的编辑器插件系统。该系统需满足党政事业单位信创要求&#xff…

作者头像 李华