尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

beautiful-react-hooks 之 useMouseState:声明式追踪鼠标坐标的 React Hook 实战指南

发布时间:2026/9/26 2:34:22

资讯中心
01
ARTICLE

beautiful-react-hooks 之 useMouseState:声明式追踪鼠标坐标的 React Hook 实战指南

beautiful-react-hooks 之 useMouseState:声明式追踪鼠标坐标的 React Hook 实战指南
前端开发工具【免费下载链接】beautiful-react-hooks A collection of beautiful and (hopefully) useful React hooks to speed-up your components and hooks development 项目地址https://gitcode.com/gh_mirrors/be/beautiful-react-hooks点击查看免费下载useMouseState是beautiful-react-hooks提供的鼠标状态 Hook它以声明式 API 返回当前鼠标指针的坐标状态clientX、clientY、screenX、screenY支持将事件监听绑定到指定 DOM 元素或全局document。读完本文你将掌握useMouseState的两种绑定方式、其返回值的完整类型定义以及它基于useMouseEvents与useEvent的底层实现原理和测试验证方式可直接用于工具提示、拖拽跟随、坐标展示等交互场景。为什么需要 useMouseState 在 React 应用中获取鼠标位置最常见的手写方案是在组件内手动addEventListener/removeEventListener管理mousemove监听这往往带来三个痛点样板代码重复、事件挂载目标不清晰、组件卸载时忘记清理监听导致内存泄漏。useMouseState的设计目标正是解决这些问题依据 docs/useMouseState.md快速获取鼠标位置一次调用即可拿到坐标状态无需手写事件逻辑灵活的事件挂载可以全局监听也可以把事件绑定到指定的 DOM 目标上自动清理监听组件卸载时由底层 Hook 自动移除事件监听器避免泄漏。它属于库中鼠标能力三件套之一与 useMouseEvents事件回调设置器和 useMouse状态 事件的组合快捷入口共同构成完整的鼠标抽象层。API 与返回类型useMouseState接受一个可选参数DOM refRefObjectTElementTElement extends HTMLElement。不传参数时事件挂载到全局document。返回一个包含四个坐标字段的普通对象初始值全部为0见 src/useMouseState.ts字段类型说明clientXnumber鼠标指针相对浏览器可视区域viewport左侧的水平坐标clientYnumber鼠标指针相对浏览器可视区域顶部的垂直坐标screenXnumber鼠标指针相对整个屏幕左侧的水平坐标screenYnumber鼠标指针相对整个屏幕顶部的垂直坐标文档中给出的完整 TypeScript 声明如下原样继承自 docs/useMouseState.md 的 Types 段落import { type RefObject } from react; /** * Returns the current state (position) of the mouse pointer. * It possibly accepts a DOM ref representing the mouse target. * If a target is not provided the state will be caught globally. */ declare const useMouseState: TElement extends HTMLElement(targetRef?: RefObjectTElement | undefined) { clientX: number; clientY: number; screenX: number; screenY: number; }; export default useMouseState;需要留意的是坐标在鼠标移动事件触发时才更新初始渲染时四个字段为0源码中的useState初始值即{ clientX: 0, clientY: 0, screenX: 0, screenY: 0 }如果希望在鼠标未进入目标区域前不展示坐标可以自行判断坐标值再决定 UI 呈现。基础用法绑定到指定 DOM 元素当需要追踪某个特定区域内的鼠标位置时传入该区域的 DOM ref 即可。事件监听只会挂载到该元素上鼠标移出区域后坐标不再更新。import { useRef } from react; import { Tag, Space, Alert } from antd; import useMouseState from beautiful-react-hooks/useMouseState; const MouseReporter () { const ref useRef(); const { clientX, clientY } useMouseState(ref); return ( DisplayDemo titleuseMediaQuery div ref{ref} Space directionvertical Alert messageMove mouse over this box to get its current coordinates typeinfo showIcon / Tag colorgreenClientX: {clientX}/Tag Tag colorgreenClientY: {clientY}/Tag /Space /div /DisplayDemo ); }; MouseReporter /关键点示例中的div ref{ref}与useMouseState(ref)必须使用同一个 ref 对象Hook 内部依赖targetRef.current来定位事件目标若 ref 尚未绑定到已挂载的 DOM 节点底层监听会在元素可用后再建立详见下文源码剖析。全局事件监听整个页面如果不提供任何 DOM refuseMouseState会把mousemove事件挂载到全局document对象上适用于需要在整个页面范围内追踪鼠标的场景例如实现全局拖拽、页面级鼠标跟随效果。import { Tag, Space, Alert } from antd; import useMouseState from beautiful-react-hooks/useMouseState; const MouseReporter () { const { clientX, clientY } useMouseState(); return ( DisplayDemo titleuseMouseState Space directionvertical Alert messageMove mouse around to get its current global coordinates typeinfo showIcon / Tag colorgreenClientX: {clientX}/Tag Tag colorgreenClientY: {clientY}/Tag /Space /DisplayDemo ); }; MouseReporter /从源码看src/useMouseEvents.ts未传 ref 时目标会被默认成window.documentconst target targetRef ?? { current: window.document } as unknown as RefObjectTElement因此全局模式下无需关心任何 DOM 引用直接调用即可。源码级原理剖析useMouseState的实现非常精简完整逻辑集中在 src/useMouseState.ts全文仅 26 行核心调用链如下const useMouseState TElement extends HTMLElement(targetRef?: RefObjectTElement) { const [state, setState] useState({ clientX: 0, clientY: 0, screenX: 0, screenY: 0 }) const { onMouseMove } useMouseEventsTElement(targetRef) onMouseMove((event: MouseEvent) { const nextState createStateObject(event) setState(nextState) }) return state }它的工作链路可以拆解为三层第一层createStateObject状态映射。每次mousemove触发时从原生MouseEvent中提取clientX、clientY、screenX、screenY四个字段组装成新状态对象src/useMouseState.ts再通过setState触发组件重渲染。第二层useMouseEvents事件回调注册。src/useMouseEvents.ts 内部通过useEvent为mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup七种鼠标事件分别创建回调设置器并返回一个Object.freeze冻结的对象。useMouseState只订阅其中的onMouseMove。第三层useEvent监听生命周期管理。src/useEvent.ts 负责真正的监听器挂载它结合createHandlerSetter见 src/factory/createHandlerSetter.ts用useRef保存回调、setter 只更新 ref 不触发重渲染保存回调函数并在useEffect中调用target.current.addEventListener(eventName, cb, options)挂载监听同时返回清理函数在卸载或依赖变化时调用removeEventListener。此外它还做了一层防御校验如果传入的 target 对象上没有current属性会抛出Unable to assign any scroll event to the given ref错误。从这段调用链可以推断useMouseState之所以能做到“自动清理”是因为监听器的添加与移除全部收敛在useEvent的useEffect副作用中组件卸载即自动释放开发者无需关心。测试验证仓库为useMouseState提供了对应的单元测试 test/useMouseState.spec.js验证了两个核心行为返回值结构调用后返回一个包含clientX、clientY、screenX、screenY四个键的对象坐标随鼠标移动更新构造一个绑定到div的 ref派发带坐标信息的MouseEvent(mousemove)断言 Hook 返回的状态与事件携带的坐标完全一致。测试同时覆盖了「无 ref 的全局调用」与「有 ref 的目标调用」两条路径可以作为你在自己项目中复刻或扩展该 Hook 时的行为基准。运行仓库测试使用npm testmocha nyc见 package.json。使用建议与延伸✅ 适合的场景依据文档 Mastering the hook 部分需要把鼠标相关逻辑抽象成自定义 Hook 时useMouseState可作为状态来源被组合进更上层的封装需要快速获取当前鼠标位置例如悬浮坐标提示、放大镜效果、拖拽元素的跟随定位。延伸阅读若只需要事件而不关心状态或想同时监听mousedown、mouseup等事件请使用 useMouseEvents注意其回调设置器应在组件体内同步调用不能异步调用也不建议用它替代 React 原生的onMouseMove等合成事件 props会失去 SyntheticEvent 的性能优势若状态与事件都需要直接使用组合了两者的 useMouse返回[state, events]元组避免分别调用两个 Hook安装与按需引入npm install beautiful-react-hooks后按import useMouseState from beautiful-react-hooks/useMouseState方式引入包内已为每个 Hook 单独配置 ESM/CJS/类型声明导出见 package.json 的exports字段。一个实用技巧useMouseState每次鼠标移动都会触发一次状态更新与组件重渲染若在全局模式下使用且渲染成本较高可考虑结合useThrottledCallback或useDebouncedCallback对消费方做节流/防抖避免高频渲染压力。赞分享前端开发工具【免费下载链接】beautiful-react-hooks A collection of beautiful and (hopefully) useful React hooks to speed-up your components and hooks development 项目地址https://gitcode.com/gh_mirrors/be/beautiful-react-hooks点击查看免费下载相关推荐如何安装 redis-py 并首次连接 Redis 完成一次 set/get 数据读写如何安装 redis py 并首次连接 Redis 完成一次 set/get 数据读写 本文解决的问题是你准备在一台机器上用 Python 操作 Redis前端开发工具beautiful-react-hooks useGlobalEvent为 window 事件监听编写声明式 React Hookbeautiful react hooks useGlobalEvent为 window 事件监听编写声明式 React Hook useGlobalEven前端开发工具Wagtail StreamField 块如何编写自定义校验并只在发布时强制必填Wagtail StreamField 块如何编写自定义校验并只在发布时强制必填 如果你在给 Wagtail 的 StreamField 写自定义块会遇到两前端开发工具上一篇5分钟快速上手Mermaid Live Editor完全免费在线图表编辑器终极指南下一篇Fladder多平台部署教程Windows、macOS、Linux与移动设备全攻略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。