React Native使用react-native-geolocation-service遇变量未定义及内存泄漏报错
React Native 定位功能两个常见问题解决方案
问题1:ReferenceError: Can't find variable: hasLocationPermission 修复方案
错误原因
你的代码存在3个核心问题:
hasLocationPermission是异步函数,componentDidMount中直接写if(hasLocationPermission)是判断函数本身是否存在,不是执行函数获取权限校验结果- 仅实现了安卓端的权限逻辑,没有兼容iOS端的定位权限校验,同时
PermissionsAndroidAPI本身仅支持安卓平台 - 函数语法存在错误,权限判断后多了无效的错误回调块,还有重复的
buttonNegative属性
修复代码
import { Platform, PermissionsAndroid } from 'react-native'; import Geolocation from 'react-native-geolocation-service'; // 跨平台定位权限申请函数 const requestLocationPermission = async () => { if (Platform.OS === 'ios') { // iOS端权限申请 const status = await Geolocation.requestAuthorization('whenInUse'); return status === 'granted'; } if (Platform.OS === 'android') { // 安卓端权限申请,修复参数错误 const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, { title: 'Cool Weather App', message: 'Cool Weather App needs access to use your location', buttonNegative: 'Cancel', buttonPositive: 'OK' } ); return granted === PermissionsAndroid.RESULTS.GRANTED; } return false; } async componentDidMount() { // 新增组件挂载标记,用于后续解决内存泄漏问题 this._isMounted = true; // 执行权限申请函数获取结果 const hasPermission = await requestLocationPermission(); if(hasPermission && this._isMounted) { this.geoWatcher = Geolocation.getCurrentPosition( (position) => { // 执行逻辑前先判断组件是否仍挂载 if (!this._isMounted) return; console.log(position); // 如有setState操作请放在该判断之后 }, (error) => { if (!this._isMounted) return; console.log(error.code, error.message); }, {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000} ); } }
问题2:Can't perform a React state update on an unmounted component 修复方案
错误原因
定位请求是异步操作,若请求未返回时你就退出了当前页面,组件已经卸载,此时回调执行setState就会触发该警告,属于典型的异步任务未及时清理导致的内存泄漏问题。
修复代码
在组件中新增componentWillUnmount生命周期函数,清理异步任务和订阅:
componentWillUnmount() { // 标记组件已卸载 this._isMounted = false; // 清除定位回调 if (this.geoWatcher) { Geolocation.clearWatch(this.geoWatcher); } // 停止定位服务 Geolocation.stopObserving(); }
额外注意事项
- iOS端需要先在
Info.plist中添加权限描述字段NSLocationWhenInUseUsageDescription,值为你要提示用户的定位用途说明 - 安卓端需要在
AndroidManifest.xml中添加权限声明:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - 若使用函数式组件,可通过
useRef存储挂载标记,在useEffect的清理函数中执行定位清除逻辑
内容的提问来源于stack exchange,提问作者CodeLover
相关产品推荐
相关产品推荐

