React Native函数组件向类组件传值异常:location始终为false
问题分析与修复方案
你的核心问题是异步逻辑顺序错误,导致导航跳转时还没拿到位置数据,具体原因和修复方法如下:
问题根源
Geolocation.getCurrentPosition是基于回调的异步API,不是Promise,外层的await不会等待它执行完成。你现在的代码里,navigation.navigate会在获取位置的回调触发前就执行,此时location还是初始的false。setLocation是React的异步状态更新函数,即使调用了setLocation(position),也不能立刻拿到更新后的location值,所以依赖这个状态跳转肯定会出错。
修复方案一:直接在位置回调里跳转(最简单高效)
把导航逻辑放到getCurrentPosition的成功回调中,确保拿到位置数据后再跳转:
export default function Dashboard({ navigation }) { const [location, setLocation] = useState(false); const onGetLocation = async () => { // 直接await权限请求,替换冗余的then写法 const res = await requestLocationPermission(); console.log("res is:", res); if (res) { Geolocation.getCurrentPosition( (position) => { // 拿到位置后直接跳转,不用等state更新 navigation.navigate("Map", position); setLocation(position); // 如果后续页面需要用到这个状态就保留 }, (error) => { console.log(error.code, error.message); setLocation(false); }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 } ); } }; return ( // ... 原有UI代码 ); }
修复方案二:封装Promise用async/await统一写法
如果更习惯用async/await的语法,可以把getCurrentPosition包装成Promise:
export default function Dashboard({ navigation }) { const [location, setLocation] = useState(false); // 封装获取位置的Promise函数 const getCurrentPositionAsync = () => { return new Promise((resolve, reject) => { Geolocation.getCurrentPosition(resolve, reject, { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }); }); }; const onGetLocation = async () => { const res = await requestLocationPermission(); if (res) { try { const position = await getCurrentPositionAsync(); setLocation(position); navigation.navigate("Map", position); } catch (error) { console.log(error.code, error.message); setLocation(false); } } }; return ( // ... 原有UI代码 ); }
额外优化建议
- 规范导航参数传递:React Navigation推荐传递结构化对象,方便后续扩展,比如:
// 跳转时 navigation.navigate("Map", { location: position }); // Map组件中接收 const { location } = this.props.route.params; - 正确使用位置数据:
Geolocation返回的position里,坐标存在coords属性下,所以Map组件的region可以改成动态计算:export default class Map extends React.Component { render() { const { location } = this.props.route.params; const defaultRegion = { latitude: 35.6762, longitude: 139.6503, latitudeDelta: 0.1, longitudeDelta: 0.1, }; // 有位置数据就用真实坐标,否则用默认值 const region = location ? { latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.1, longitudeDelta: 0.1, } : defaultRegion; return ( <View style={{ flex: 1 }}> <MapView style={{ flex: 1 }} region={region}></MapView> </View> ); } }
内容的提问来源于stack exchange,提问作者Kireet Bhat
相关产品推荐
相关产品推荐

