ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

usehooks-ts `useCountdown` 倒计时 Hook 完整指南:参数、源码原理与实战示例

usehooks-ts `useCountdown` 倒计时 Hook 完整指南:参数、源码原理与实战示例 前端【免费下载链接】usehooks-tsReact hook library, ready to use, written in Typescript.项目地址https://gitcode.com/gh_mirrors/us/usehooks-ts点击查看免费下载useCountdown是 usehooks-ts 提供的一个简单、开箱即用的倒计时自定义 Hook支持递增与递减两种方向并在到达指定停止值countStop时自动停下。本文以 useCountdown 官方文档 为主体结合仓库源码与测试用例带你掌握新版本 API 的全部参数、返回的控制器方法、底层实现原理以及可直接复制的实战示例。一、概览一个 Hook 搞定倒计时倒计时是前端最常见的交互需求之一验证码发送后的 60 秒重发倒计时、限时活动的剩余时间、游戏或测验的计时……手写这类逻辑通常要同时管理setInterval的创建与清理、计数状态、开始/停止开关代码容易散落且难以复用。useCountdown把这一切封装进一个 Hook 中。它基于useCounter、useBoolean、useInterval三个基础 Hook 组合而成调用后返回当前计数值与三个控制器方法开始、停止、重置开发者无需关心定时器的生命周期管理。文档明确指出A simple countdown implementation. Support increment and decrement.即一个简单的倒计时实现支持递增与递减。新版本接口变更重要useCountdown.md开头特别提示新版本 useCountdown 将在下一个大版本中废弃旧版本The new useCountdown is deprecating the old one on the next major version。新旧版本在调用参数上存在映射关系迁移时需注意新版本参数旧版本参数说明countStartseconds倒计时起始数值intervalMsinterval每次变化的间隔毫秒isIncrement新增是否递增默认false表示递减countStop新增停止数值到达后自动停止新版本额外支持countStop与isIncrement并会在计数值到达countStop时自动停止Will stop when atcountStop。二、参数详解CountdownOptions从 useCountdown.ts 的源码类型定义可以看出useCountdown接收一个对象参数CountdownOptionstype CountdownOptions { /** The countdowns starting number, initial value of the returned number. */ countStart: number /** * The countdowns interval, in milliseconds. * default 1000 */ intervalMs?: number /** * True if the countdown is increment. * default false */ isIncrement?: boolean /** * The countdowns stopping number. Pass -Infinity to decrease forever. * default 0 */ countStop?: number }各参数说明参数类型必填默认值含义countStartnumber是—倒计时的起始数值也是返回值count的初始值intervalMsnumber否1000每次递增/递减的间隔单位毫秒isIncrementboolean否false为true时递增计数为false默认时递减计数countStopnumber否0倒计时的停止数值到达后自动停止传入-Infinity可实现无限递减需要特别关注的两个细节源码 JSDoc 与测试均可印证countStop的默认值是0递减模式下计数到0时自动停止这也是最常见的验证码倒计时场景。countStop传入-Infinity表示递减到永远即不设置停止边界计数会一直递减下去。三、返回值CountdownControllersuseCountdown返回一个元组[number, CountdownControllers]第一个元素是当前计数值第二个元素是三个控制器方法源码见 useCountdown.tstype CountdownControllers { /** Start the countdown. */ startCountdown: () void /** Stop the countdown. */ stopCountdown: () void /** Reset the countdown. */ resetCountdown: () void }方法作用startCountdown启动倒计时开始按intervalMs周期递增/递减stopCountdown停止倒计时保留当前计数值resetCountdown停止倒计时并将计数重置为countStart初始值典型解构用法const [count, { startCountdown, stopCountdown, resetCountdown }] useCountdown({ countStart: 10, intervalMs: 1000, isIncrement: false, })这正是 useCountdown.ts 中 JSDoc 给出的官方示例形态。四、基础实战示例可直接运行的倒计时组件仓库提供了完整可运行的演示组件 useCountdown.demo.tsx它演示了「从 60 开始递减 可动态调整间隔 开始/停止/重置」的完整用法import { useState } from react import type { ChangeEvent } from react import { useCountdown } from ./useCountdown export default function Component() { const [intervalValue, setIntervalValue] useStatenumber(1000) const [count, { startCountdown, stopCountdown, resetCountdown }] useCountdown({ countStart: 60, intervalMs: intervalValue, }) const handleChangeIntervalValue (event: ChangeEventHTMLInputElement) { setIntervalValue(Number(event.target.value)) } return ( div pCount: {count}/p input typenumber value{intervalValue} onChange{handleChangeIntervalValue} / button onClick{startCountdown}start/button button onClick{stopCountdown}stop/button button onClick{resetCountdown}reset/button /div ) }这个示例展示了两个关键点intervalMs可以动态改变通过useState维护间隔值将其传入 Hook 后即使倒计时运行中修改间隔useInterval也会以新间隔重建定时器原理见下文。三按钮控制模型start/stop/reset分别对应startCountdown/stopCountdown/resetCountdown覆盖了倒计时组件的全部控制需求。在验证码场景中只需将按钮替换为发送验证码并在count 0时禁用按钮即可。五、源码原理三个基础 Hook 的组合useCountdown之所以实现简洁是因为它把状态、开关、定时器三件事分别委托给了仓库内已有的基础 Hook。完整实现见 useCountdown.tsexport function useCountdown({ countStart, countStop 0, intervalMs 1000, isIncrement false, }: CountdownOptions): [number, CountdownControllers] { const { count, increment, decrement, reset: resetCounter } useCounter(countStart) const { value: isCountdownRunning, setTrue: startCountdown, setFalse: stopCountdown } useBoolean(false) const resetCountdown useCallback(() { stopCountdown() resetCounter() }, [stopCountdown, resetCounter]) const countdownCallback useCallback(() { if (count countStop) { stopCountdown() return } if (isIncrement) { increment() } else { decrement() } }, [count, countStop, decrement, increment, isIncrement, stopCountdown]) useInterval(countdownCallback, isCountdownRunning ? intervalMs : null) return [count, { startCountdown, stopCountdown, resetCountdown }] }5.1 计数状态来自useCounter计数值由useCounter(countStart)提供。在 useCounter.ts 中count通过useState(initialValue ?? 0)初始化并封装了incrementx x 1、decrementx x - 1与reset重置为初始值等稳定回调。useCountdown只借用其中的count、increment、decrement、reset因此计数值的变化始终遵循每次 ±1的步长。5.2 运行开关来自useBoolean倒计时的启停由useBoolean(false)驱动useBoolean.ts 提供了setTrue/setFalse等工具方法。在useCountdown中setTrue直接暴露为startCountdownsetFalse直接暴露为stopCountdown布尔值isCountdownRunning作为定时器的开关信号。5.3 定时器来自useInterval核心循环由useInterval驱动useInterval(countdownCallback, isCountdownRunning ? intervalMs : null)useInterval.ts 的语义是delay为null时不创建定时器相当于清除为数字时按毫秒周期执行回调。因此未调用startCountdown时isCountdownRunning为falsedelay为null定时器不存在调用startCountdown后delay变为intervalMs定时器启动停止时delay回到null定时器被清理。值得一提的是useInterval内部用useRef保存最新回调因此countdownCallback即使每次渲染都变化也不会导致定时器频繁重建除非delay变化。5.4 停止逻辑到达countStop自动刹车countdownCallback在每次定时器触发时首先检查if (count countStop) { stopCountdown() return }当计数值等于countStop时立即调用stopCountdown()关闭定时器并终止后续的递增/递减从而把计数钉在停止值上。这就是文档所述 Will stop when atcountStop 的实现位置。六、边界行为与测试验证仓库中的 useCountdown.test.ts 使用 Vitest 的假定时器vitest.useFakeTimers()系统验证了上述全部行为也是理解 Hook 语义的最佳活文档测试场景配置验证行为返回可调用函数countStart: 60, intervalMs: 500初始值60三个控制器均为函数递增模式isIncrement: true, intervalMs: 500推进1000ms后计数值为62每次 1递减模式默认参数推进1000ms后计数值为58每次 -1自定义intervalMsintervalMs: 500推进500ms后计数值为59默认countStop: 0countStart: 60推进60 * 1000ms后停在0继续推进仍为0自定义countStopcountStart: 60, countStop: 30推进30 * 1000ms后停在30不再变化停止功能默认参数start后推进2000ms计数58stop后推进3000ms仍为58反向递增停止countStart: 10, countStop: 20, isIncrement: true递增到20后自动停止继续推进仍为20重置功能默认参数递减后调用resetCountdown计数值恢复为60其中「反向倒计时」用例countStart: 10→countStop: 20递增模式证明countStop不要求小于countStart配合isIncrement: true可以实现从 10 数到 20的正向计时停止逻辑对递增/递减方向一视同仁。七、与其他 Hook 的关系useCountdown的文档页列出了四个密切相关、可组合使用的 Hook对应源码均位于仓库 src 目录 下useBoolean()提供setTrue/setFalse/toggle等布尔状态工具是useCountdown启停开关的底层来源useToggle()基于useBoolean的布尔切换封装适合管理是否显示倒计时等 UI 状态useCounter()提供increment/decrement/reset/setCount是计数值的底层来源useInterval()以delay为null即清除定时器的方式驱动倒计时循环。理解这层组合关系后你既可以直接使用useCountdown也可以在特殊需求下例如需要setCount直接跳转到任意值退回到useCounteruseInterval自行组装。八、使用建议与注意事项新老 API 迁移如果你正在使用旧版useCountdown({ seconds, interval })请按第一节的映射表迁移为countStart/intervalMs并注意旧版没有countStop与isIncrement。无限递减需要无边界递减时显式传入countStop: -Infinity源码 JSDoc 明确提示 Pass-Infinityto decrease forever。递增方向默认isIncrement: false是递减做正向计时如从 0 数到目标值时记得设置isIncrement: true并给出大于countStart的countStop。动态间隔intervalMs支持在运行中动态修改示例组件useCountdown.demo.tsx演示了通过useState驱动间隔值变化的做法。开始前计数不动未调用startCountdown之前count始终保持countStart因为定时器在isCountdownRunning为false时根本不存在。只在到达停止值时自动停止手动stopCountdown不会重置计数如需停止并归位请调用resetCountdown其实现为stopCountdown()resetCounter()见 useCountdown.ts。结语useCountdown用极小的 API 表面一个配置对象 一个元组返回值覆盖了倒计时的全部核心诉求递减、递增、自动停止、手动启停与重置。通过阅读 useCountdown.ts、useCountdown.test.ts 与 useCountdown.demo.tsx 三份文件你不仅能直接上手使用还能看清它如何优雅地组合useCounter、useBoolean、useInterval三个基础 Hook——这种组合式设计正是 usehooks-ts 这类 React Hook 库值得借鉴的架构思路。赞分享前端【免费下载链接】usehooks-tsReact hook library, ready to use, written in Typescript.项目地址https://gitcode.com/gh_mirrors/us/usehooks-ts点击查看免费下载相关推荐ahooks useCountDown 倒计时 Hook 完全指南API 详解、毫秒精度与源码实现剖析ahooks useCountDown 倒计时 Hook 完全指南API 详解、毫秒精度与源码实现剖析 useCountDown 是 ahooks位于 pa前端ahooks useCountDown 倒计时 Hook 完全指南API 详解、精度陷阱与实战场景ahooks useCountDown 倒计时 Hook 完全指南API 详解、精度陷阱与实战场景 导读 useCountDown 是 ahooksGitH前端usehooks-ts useScreen Hook 完整指南实时追踪 window.screen 屏幕对象兼容防抖与 SSRusehooks ts useScreen Hook 完整指南实时追踪 window.screen 屏幕对象兼容防抖与 SSR useScreen 是 us前端上一篇SOCD Cleaner终极指南彻底解决游戏键盘方向冲突的免费开源神器下一篇5分钟掌握PUBG罗技鼠标宏告别压枪烦恼的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表