在useFocusEffect中使用watchPositionAsync报错,求解决方法
解决useFocusEffect中使用watchPositionAsync的返回值错误问题
你遇到的问题核心是:useFocusEffect 的回调函数只能返回清理函数(或者不返回任何值),但你的代码里返回了 getLocation() 这个异步函数执行后的 Promise,这就触发了错误提示。
我们可以通过以下方式修改代码来解决:
- 用
useRef保存位置订阅的引用,确保在组件生命周期内能稳定访问到订阅实例,方便后续清理 - 在
useCallback内部定义异步函数并立即执行,不要把异步函数作为回调的返回值 - 单独返回一个同步的清理函数,在组件失去焦点时执行取消订阅的逻辑
修改后的完整代码如下:
import { useFocusEffect, useCallback, useRef } from 'react'; import { Accuracy, getPermissionsAsync, watchPositionAsync } from 'expo-location'; // 组件内部代码 useFocusEffect( useCallback(() => { // 用ref存储订阅实例,避免异步操作后丢失引用 const locationSubscriptionRef = useRef(null); const getLocation = async () => { await getPermissionsAsync(); // 将订阅实例存入ref locationSubscriptionRef.current = await watchPositionAsync( { accuracy: Accuracy.BestForNavigation, timeInterval: 5000 }, (location) => { console.log('获取到位置信息:', location); } ); }; // 立即执行异步逻辑,不将其作为返回值 getLocation(); // 返回同步的清理函数,符合useFocusEffect的要求 return () => { if (locationSubscriptionRef.current) { locationSubscriptionRef.current.remove(); } }; }, []) );
改动说明
useRef的作用是存储订阅实例,因为异步函数执行是滞后的,用ref能保证后续清理时能拿到正确的订阅对象- 异步函数
getLocation被直接调用,不会成为useFocusEffect回调的返回值,避免了返回Promise的问题 - 最终返回的是同步的清理函数,当组件失去焦点时会自动执行,移除位置监听,防止内存泄漏
内容的提问来源于stack exchange,提问作者Omar Khaled
相关产品推荐
相关产品推荐

