ARTICLE DETAIL

资讯详情

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

react-use 的 useIdle Hook 详解:基于交互事件实时追踪用户空闲状态

react-use 的 useIdle Hook 详解:基于交互事件实时追踪用户空闲状态 react-use 的 useIdle Hook 详解基于交互事件实时追踪用户空闲状态【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use导读useIdle是 react-usepackage.json 中版本为 17.6.1提供的一个sensor传感器类 Hook用于追踪当前页面上的用户是否处于空闲idle状态。本文以 docs/useIdle.md 为骨架结合 src/useIdle.ts 源码与 stories/useIdle.story.tsx 演示完整讲解其用法、参数语义与底层实现原理帮助你在此基础上实现自动暂停、节电模式、安全锁定、在线状态提示等实战功能。useIdle 是什么useIdle在官方 README.md 中被描述为 tracks whether user is being inactive即通过监听用户的交互事件来判断其是否处于空闲状态。它归属于 react-use 的 Sensors 分类对应 docs/Sensors.md 文档体系与useMouse、useScroll、useKeyPress等 Hook 一样将浏览器事件抽象为可响应的 React 状态。Hook 的核心能力是用户在一段时间内没有任何交互鼠标、键盘、触摸、滚动、窗口变化等时返回值切换为true一旦用户恢复交互返回值立即切回false并重新开始计时支持自定义空闲判定时长与初始状态。快速上手根据 docs/useIdle.md 的 Usage 示例最简单的用法如下import {useIdle} from react-use; const Demo () { const isIdle useIdle(3e3); return ( div divUser is idle: {isIdle ? Yes : Nope}/div /div ); };useIdle会从 src/index.ts 作为具名导出对外暴露对应源码第 35 行export { default as useIdle } from ./useIdle;因此直接import { useIdle } from react-use即可使用。一个可调节延迟的交互式演示仓库的 stories/useIdle.story.tsx 提供了一个更贴近实战的 Storybook 演示用useState保存延迟毫秒数通过input typenumber实时修改并传入useIdle界面同步显示 User is idle: Yes / No。这验证了useIdle对ms参数是响应式的——延迟变化后判定逻辑会随之更新import { storiesOf } from storybook/react; import * as React from react; import { useIdle } from ../src; const Demo () { const [idleDelay, setIdleDelay] React.useState(3e3); const isIdle useIdle(idleDelay); return ( div Idle delay ms:{ } input typenumber value{idleDelay} onChange{({ target }) setIdleDelay(target.value)} / divUser is idle: {isIdle ? Yes : No}/div /div ); }; storiesOf(Sensors/useIdle, module) .add(Docs, () ShowDocs md{require(../docs/useIdle.md)} /) .add(Demo, () Demo /);API 参考与参数语义依据 docs/useIdle.md 的 Reference 章节useIdle(ms, initialState);参数类型默认值说明msnumber60e3一分钟用户空闲多少毫秒后判定为 idleinitialStatebooleanfalse初始是否把用户视为空闲默认认为用户一开始是活跃的对照 src/useIdle.ts 第 812 行的真实签名const useIdle ( ms: number oneMinute, // oneMinute 60e3 initialState: boolean false, events: string[] defaultEvents ): boolean {可以看到文档中的两个参数与源码完全一致返回值是一个booleantrue表示用户当前被判定为空闲false表示用户处于活跃状态。源码中隐藏的第三个参数events值得注意的是源码比文档多暴露了一个未在文档中记录的第三参数events默认值为defaultEvents见源码第 5 行const defaultEvents [mousemove, mousedown, resize, keydown, touchstart, wheel];也就是说useIdle默认监听以下六类窗口事件来判定用户活跃mousemove/mousedown鼠标移动与点击resize窗口尺寸变化keydown键盘按键touchstart触摸屏触摸wheel滚轮滚动。如果你希望自定义什么算活跃可以传入第三参数例如只把键盘与鼠标点击视为活跃交互const isIdle useIdle(5e3, false, [keydown, mousedown]);底层实现原理剖析完整源码位于 src/useIdle.ts其实现可拆解为四条核心机制。1. 状态管理useState mounted 保护Hook 首先用useState(initialState)保存空闲状态源码第 13 行随后在useEffect内部维护一个mounted布尔值与localState缓存let mounted true; let timeout: any; let localState: boolean state; const set (newState: boolean) { if (mounted) { localState newState; setState(newState); } };set是唯一的状态写入入口只有在组件仍然挂载时才会更新 React 状态从机制上避免了组件卸载后的 setState 警告。2. 事件节流与计时重置50ms 节流 setTimeout用户交互会被统一交给onEvent处理而onEvent用throttle-debounce包见 package.json 依赖的throttle(50, ...)做了50ms 节流防止高频事件如 mousemove、scroll频繁触发重排const onEvent throttle(50, () { if (localState) { set(false); // 有交互 → 立即从 idle 恢复为活跃 } clearTimeout(timeout); // 取消上一次计时 timeout setTimeout(() set(true), ms); // 重新计时 ms 毫秒 });这段逻辑揭示了判定的完整闭环任意监听到的交互发生若当前是 idlelocalState true立即置回活跃清除旧计时器重新启动一个ms毫秒的计时器计时器到期触发set(true)用户进入空闲状态。3. 页面可见性兜底visibilitychange仅靠窗口事件存在一个盲区用户切换标签页或最小化窗口后可能长时间没有交互事件产生此时setTimeout会照常到期并置为 idle——这通常符合预期。但若用户切回页面时源码会通过visibilitychange立即唤醒判定const onVisibility () { if (!document.hidden) { onEvent(); // 页面重新可见 → 视为一次交互重置空闲计时 } };这个visibilitychange监听绑定在document上源码第 43 行与绑定在window上的六个交互事件源码第 4042 行经由 src/misc/util.ts 的on工具函数完成addEventListener共同构成完整的监听体系。4. 初始化与清理useEffect挂载时立即启动第一个计时器源码第 45 行timeout setTimeout(() set(true), ms);这意味着只要用户在ms毫秒内无任何交互Hook 就会触发 idle 状态无需等待第一次事件。清理函数源码第 4754 行会将mounted置为false阻止后续 setState通过 src/misc/util.ts 的off工具函数对events列表逐一执行removeEventListener解绑document上的visibilitychange。此外useEffect的依赖数组为[ms, events]源码第 55 行当这两个参数变化时会整体重建监听与计时。5. 从依赖看实现约束throttle-debounce是 package.json 中声明的直接依赖throttle(50, ...)的节流窗口为 50msHook 依赖 DOM APIwindow、document属于浏览器环境专用 Hook。从 src/misc/util.ts 的on/off实现可见若目标对象不存在如 SSR 场景下window为undefined会安全跳过监听而不抛错。实战场景与注意事项基于上述机制useIdle可用于以下典型场景自动暂停播放视频或轮播图在用户离开后自动暂停配合isIdle切换播放状态会话安全锁定后台管理系统在用户闲置 N 分钟后锁定屏幕或提示重新登录节电与资源释放空闲时停止轮询、动画或实时数据推送恢复交互后再继续在线状态提示类似聊天软件中离开/在线状态的自动切换。使用时注意以下几点ms的最小实践值由于交互事件本身有 50ms 节流且判定依赖setTimeoutms过小如小于 100ms会导致状态在活跃/空闲之间频繁抖动建议按业务语义设置如 3s5min自定义events会替换默认六种事件传入第三参数时请自行覆盖所需的全部交互类型切换标签页行为页面隐藏期间计时照常推进切回页面时会被visibilitychange视为一次交互并重置计时若业务需要离开页面即视为空闲需结合document.hidden自行判断initialState默认false组件首次渲染即认为用户活跃若希望首帧即显示空闲如静默加载场景可传入true。相关资源官方文档docs/useIdle.md核心实现src/useIdle.ts事件工具函数src/misc/util.ts具名导出src/index.tsStorybook 交互演示stories/useIdle.story.tsx项目总览README.md【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表