
react-use 的 useGeolocation在 React 组件中追踪用户地理位置的传感器 Hook 实战指南【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use导读useGeolocation是 react-use 提供的传感器SensorHook 之一用于在 React 组件中实时追踪用户设备的地理位置并将坐标、精度、速度等地理信息以响应式 state 的形式暴露给组件。本文将以 docs/useGeolocation.md 为主线结合 src/useGeolocation.ts 的源码实现带你掌握它的基础用法、完整返回状态、PositionOptions配置参数、错误处理机制与底层原理从而在位置签到、导航地图、附近推荐等场景中直接落地使用。功能概览什么是 useGeolocation在 react-use 中Sensor Hooks 专门用于监听某个外部接口的变化并强制组件携带最新状态重新渲染参见 docs/Sensors.md。useGeolocation正是这一类 Hook它封装了浏览器原生的 Geolocation APInavigator.geolocation持续追踪用户的地理位置。根据 README.md 的描述它的定位是 tracks geo location state of users device即追踪用户设备的地理位置状态。它接收可选的 PositionOptions 配置enableHighAccuracy、timeout、maximumAge并把位置信息包装成统一的响应式状态对象返回。作为传感器 Hook它的核心价值在于开箱即用无需手动管理getCurrentPosition/watchPosition/clearWatch的生命周期响应式状态位置变化自动触发组件重渲染可直接用于渲染或接入业务逻辑统一的错误处理将定位失败原因权限拒绝、超时、位置不可用收敛为 state 中的error字段。快速上手基础用法useGeolocation的用法非常简洁无需任何参数即可开始追踪import {useGeolocation} from react-use; const Demo () { const state useGeolocation(); return ( pre {JSON.stringify(state, null, 2)} /pre ); };在 stories/useGeolocation.story.tsx 中react-use 自带的 Storybook Demo 正是这样实现的——直接调用useGeolocation()并将返回的state序列化渲染到pre标签中方便直观地查看实时地理位置数据。useGeolocation通过 src/index.ts 从库的根入口导出export { default as useGeolocation } from ./useGeolocation因此既可以按需单独引入也可以与其他 Hook 一起使用命名导入// 按需引入推荐避免引入无关依赖 import useGeolocation from react-use/lib/useGeolocation; // 命名导入配合 tree shaking import {useGeolocation} from react-use;返回状态详解GeoLocationSensorStateuseGeolocation返回一个状态对象其完整类型定义在 src/useGeolocation.ts 中名为GeoLocationSensorStateinterface GeoLocationSensorState { loading: boolean; accuracy: number | null; altitude: number | null; altitudeAccuracy: number | null; heading: number | null; latitude: number | null; longitude: number | null; speed: number | null; timestamp: number | null; error?: Error | IGeolocationPositionError; }各字段含义与来源如下表所示字段类型说明loadingboolean是否正在获取位置。初始为true首次定位成功或失败后变为falselatitudenumber \| null纬度单位为度十进制范围 -90 到 90longitudenumber \| null经度单位为度十进制范围 -180 到 180accuracynumber \| null经纬度精度单位为米altitudenumber \| null海拔高度单位为米设备不支持时为nullaltitudeAccuracynumber \| null海拔精度单位为米设备不支持时为nullheadingnumber \| null设备移动方向相对正北的顺时针角度0360 度静止或设备不支持时为nullspeednumber \| null设备移动速度单位为米/秒设备不支持时为nulltimestampnumber \| null位置数据对应的时间戳errorError \| IGeolocationPositionError可选定位失败时的错误信息成功时不存在该字段初始状态从源码可以看到Hook 在创建时即初始化了默认状态src/useGeolocation.tsconst [state, setState] useStateGeoLocationSensorState({ loading: true, accuracy: null, altitude: null, altitudeAccuracy: null, heading: null, latitude: null, longitude: null, speed: null, timestamp: Date.now(), });也就是说组件首次渲染时loading为true各坐标字段为nulltimestamp为调用时的当前时间。你可以基于loading字段渲染加载态例如const Demo () { const state useGeolocation(); if (state.loading) { return div正在获取位置…/div; } if (state.error) { return div定位失败{state.error.message}/div; } return ( div 纬度{state.latitude}经度{state.longitude}精度 ±{state.accuracy} 米 /div ); };位置更新回调当浏览器返回定位结果时源码通过onEvent回调将event.coords中的各坐标字段逐一映射进 state并把loading置为falsesrc/useGeolocation.tsconst onEvent (event: any) { if (mounted) { setState({ loading: false, accuracy: event.coords.accuracy, altitude: event.coords.altitude, altitudeAccuracy: event.coords.altitudeAccuracy, heading: event.coords.heading, latitude: event.coords.latitude, longitude: event.coords.longitude, speed: event.coords.speed, timestamp: event.timestamp, }); } };注意event.timestamp取自 Geolocation API 返回事件本身的时间戳而非Date.now()这样能准确反映设备定位完成的时刻。配置参数PositionOptionsuseGeolocation的完整函数签名见 docs/useGeolocation.md 的 Reference 部分为useGeolocation(options: PositionOptions)其中options是浏览器标准 Geolocation API 定义的PositionOptions对象三个可选字段及建议取值如下配置项类型默认值说明enableHighAccuracybooleanfalse是否请求高精度定位。设为true时精度更高但可能更耗电、响应更慢timeoutnumberInfinity不超时允许设备返回位置的最长等待时间单位为毫秒。超时后触发TIMEOUT错误maximumAgenumber0允许复用缓存位置的最大时限单位为毫秒。设为0表示始终获取新位置设为较大值可减少定位等待实际使用时可以按场景传入配置例如在高精度需求的导航场景中import {useGeolocation} from react-use; const App () { const state useGeolocation({ enableHighAccuracy: true, timeout: 5000, maximumAge: 0, }); // ... };从源码可见这份options会被原样透传给navigator.geolocation.getCurrentPosition和navigator.geolocation.watchPositionsrc/useGeolocation.ts因此其行为完全遵循浏览器标准无需在 Hook 层做额外转换。源码剖析定位、监听与清理的完整链路src/useGeolocation.ts 的实现非常精简整体逻辑分为三步都集中在useEffect中useEffect(() { navigator.geolocation.getCurrentPosition(onEvent, onEventError, options); watchId navigator.geolocation.watchPosition(onEvent, onEventError, options); return () { mounted false; navigator.geolocation.clearWatch(watchId); }; }, []);1. 一次性获取当前位置navigator.geolocation.getCurrentPosition(onEvent, onEventError, options)用于在 Hook 挂载时立即获取一次当前位置。若成功通过onEvent更新 state若失败通过onEventError写入错误。2. 持续监听位置变化navigator.geolocation.watchPosition(onEvent, onEventError, options)注册一个持续监听器设备位置一旦变化就会再次触发onEvent从而驱动组件实时重渲染。这正是传感器 Hook语义的体现——位置变化被转化为 React 状态更新。3. 卸载时清理useEffect的清理函数做了两件事将mounted置为false防止组件卸载后异步回调仍去调用setState避免在已卸载组件上更新状态的警告与内存问题调用navigator.geolocation.clearWatch(watchId)注销监听器释放浏览器资源。值得注意的是useEffect的依赖数组为空[]意味着定位监听只在组件挂载时注册一次、卸载时清理一次options变化不会导致监听重建。错误处理兼容两种错误类型源码在文件头部专门定义了一个兼容接口IGeolocationPositionErrorsrc/useGeolocation.tsexport interface IGeolocationPositionError { readonly code: number; readonly message: string; readonly PERMISSION_DENIED: number; readonly POSITION_UNAVAILABLE: number; readonly TIMEOUT: number; }正如源码注释所说明的由于PositionError在 TypeScript 4.1.x 中被重命名为GeolocationPositionError为了在不同 TypeScript 版本下编译不报错react-use 自己定义了兼容接口。错误回调onEventError的逻辑是const onEventError (error: IGeolocationPositionError) mounted setState((oldState) ({ ...oldState, loading: false, error }));它保留原有字段、将loading置为false并写入error。开发者可以根据error.code区分失败原因error.PERMISSION_DENIED1用户拒绝了位置权限error.POSITION_UNAVAILABLE2无法获取位置如设备定位模块不可用error.TIMEOUT3定位超时通常与options.timeout配合出现。实战应用场景与注意事项典型应用场景位置展示将latitude/longitude传给地图组件如自定义地图 marker 定位附近推荐结合accuracy过滤不可靠坐标实现附近门店/好友类功能运动轨迹利用speed、heading展示实时速度与方向海拔相关借助altitude实现登山、骑行等户外场景的垂直信息展示。注意事项必须开启权限Geolocation API 要求页面在安全上下文HTTPS中运行且用户需授权位置权限被拒绝后error.code为PERMISSION_DENIEDUI 上应给出友好提示与引导。首帧为加载态loading初始为true坐标字段为null渲染前务必做好判空处理避免对null直接取属性。高精度有代价enableHighAccuracy: true会增大耗电与定位延迟非必要场景建议保持默认。监听生命周期由 Hook 托管组件卸载时监听器会被自动clearWatch无需手动处理。相关资源本文主体文档docs/useGeolocation.md完整源码实现src/useGeolocation.ts库入口导出src/index.ts交互式 Demostories/useGeolocation.story.tsx传感器 Hook 总览docs/Sensors.md安装与按需引入方式docs/Usage.md【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考