You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在useFocusEffect中使用watchPositionAsync报错,求解决方法

解决useFocusEffect中使用watchPositionAsync的返回值错误问题

你遇到的问题核心是:useFocusEffect 的回调函数只能返回清理函数(或者不返回任何值),但你的代码里返回了 getLocation() 这个异步函数执行后的 Promise,这就触发了错误提示。

我们可以通过以下方式修改代码来解决:

  1. 用 useRef 保存位置订阅的引用,确保在组件生命周期内能稳定访问到订阅实例,方便后续清理
  2. 在 useCallback 内部定义异步函数并立即执行,不要把异步函数作为回调的返回值
  3. 单独返回一个同步的清理函数,在组件失去焦点时执行取消订阅的逻辑

修改后的完整代码如下:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:28:09