0Pricing
React Academy · 课时

实现 useThrottle 自定义钩子

构建 useThrottle 钩子,限制滚动等快速事件期间值的更新频率

实现 useThrottle 自定义钩子 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

节流比防抖更难

防抖只需在每次事件发生时重置计时器。节流则必须主动跟踪上次执行的时间,并判断是否已经经过足够长的时间以再次执行。这需要在多次渲染之间保存时间戳,因此实现起来比防抖稍微复杂一些。

使用 useRef 保存 lastRunTime

上次执行的时间戳必须在多次渲染之间持久保存,同时不能自行触发重新渲染,因此 useRef 是合适的工具。请将时间戳存储为 const lastRunTime = useRef(Date.now())。与状态不同,更新引用不会触发重新渲染,因此节流逻辑可以高效运行,不会产生额外的渲染周期。

钩子签名

useThrottle(value, delay) 钩子会返回输入值经过节流处理的版本。它的接口约定与 useDebounce 类似:接受任意值和以毫秒为单位的延迟,并返回经过节流处理的值。组件可以用相同方式使用它,因此它是适用于不同计时语义的直接替代方案。

后沿实现

后沿节流会在每个时间间隔结束时更新值。当新值到达时,请为剩余的时间间隔安排一个 setTimeout:delay - (Date.now() - lastRunTime.current)。计时器触发时,更新状态并记录新的 lastRunTime。在清理过程中取消之前的计时器。

前沿实现

前沿节流会立即应用第一个值,并在时间间隔到期前忽略后续值。请检查:如果 Date.now() - lastRunTime.current >= delay,就更新状态并记录时间;否则跳过更新。这样首次操作会立即得到反馈,随后进入冷却期。

结合前沿与后沿

最佳用户体验通常会结合两者:立即响应第一个事件(前沿),然后确保时间间隔结束后也应用最终状态(后沿)。这意味着用户会先看到快速响应,并且在移动停止后始终应用最终稳定值,从而避免结束状态过时。

使用 useRef 存储计时器 ID

请将待处理的计时器 ID 存储在 useRef 中:const timeoutRef = useRef(null)。安排新计时器之前,请调用 clearTimeout(timeoutRef.current),以取消任何已有的计时器。这样可以防止多个计时器相互重叠,否则它们会在单个节流时间间隔内触发多次更新。

卸载时清理

组件卸载时,useEffect 的清理函数应调用 clearTimeout(timeoutRef.current),以取消任何待处理的后沿更新。否则,待处理的计时器会在组件卸载后触发,尝试更新已卸载组件的状态,并可能导致 React 警告。

节流回调替代方案

您可以创建基于 useCallback 的节流钩子,而不是使用基于值的钩子:useThrottledCallback(fn, delay) 会返回一个经过节流处理的函数。这种方式在需要节流的是函数调用(例如分析数据跟踪器)而不是响应式值时更加灵活。

使用模拟计时器测试节流

在 Jest 测试中,请使用 jest.useFakeTimers() 来控制时间。设置延迟为 1000 毫秒的节流,快速触发 10 次值变更,然后将模拟时间推进 500 毫秒,并检查是否只发生了 1 或 2 次更新。再推进 500 毫秒,验证后沿更新是否触发。这样可以确定性地验证节流行为。

React 模型中的节流

React 会在渲染期间批量处理状态更新。在此模型中,对状态更新执行节流可以顺利工作。不过请注意,在 React 18 并发模式下,渲染可能会被中断。节流逻辑本身基于 Date.now() 获取的实际时钟时间,因此不受 React 调度影响。

节流的后沿与前沿

“后沿”节流会在哪个边沿触发?

课程回顾:useThrottle 钩子

节流需要使用 useRef 跟踪上次执行时间。该钩子可以实现前沿(立即执行)、后沿(延迟执行)或两者兼具的行为。请始终将计时器 ID 存储在引用中,并在清理时取消它。在基于函数的使用场景中,优先采用 useThrottledCallback 模式。使用模拟计时器进行测试,以确保可靠性。

常见问题解答

「实现 useThrottle 自定义钩子」课时是免费的吗?

是的 — 「实现 useThrottle 自定义钩子」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「实现 useThrottle 自定义钩子」这节课中我会学到什么?

构建 useThrottle 钩子,限制滚动等快速事件期间值的更新频率 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「实现 useThrottle 自定义钩子」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 防抖与节流为何对界面很重要
  2. 实现 useDebounce 自定义钩子
  3. 实现 useThrottle 自定义钩子
  4. 实际应用:搜索、滚动和调整大小
← 返回 React Academy