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

Expo环境下使用expo-web-browser时Linking.addEventListener不触发问题

问题原因
  • 监听注册时机错误:WebBrowser.openBrowserAsync 是异步阻塞方法,只有当用户手动关闭内置浏览器,或者浏览器跳转到外部应用离开时,该Promise才会resolve。你将Linking.addEventListener写在await语句之后,相当于浏览器关闭后才注册监听,自然无法收到浏览器运行期间的URL回调。
  • 事件监听引用不匹配:注册监听时你传入的是匿名箭头函数,移除监听时传入的是urlChangeHandler,两个函数引用不一致,会导致监听无法正常移除,引发内存泄漏。
  • 能力边界误解:Linking.addEventListener 只能监听到其他应用跳回当前应用的deeplink回调,expo-web-browser 基于系统原生的Chrome自定义标签/ASWebAuthenticationSession实现,应用层无法直接获取浏览器内部的页面跳转记录,只有当浏览器跳转至你应用的自定义Scheme时才会触发该事件。
修复方案

1. 配置应用自定义Scheme

首先在项目的app.json或app.config.js中添加Scheme配置,示例如下:

{
  "expo": {
    "scheme": "your-custom-scheme"
  }
}

你需要跳转的目标页面,最终回调时要使用your-custom-scheme://xxx格式的链接,才能触发当前应用的Linking事件。如果是在Expo Go环境下开发测试,默认的Scheme为exp://。

2. 调整代码逻辑

将监听注册时机提前到打开浏览器之前,推荐在组件挂载阶段注册,组件卸载时自动移除:

import { useEffect } from 'react';
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';

// 组件内逻辑
const YourComponent = () => {
  useEffect(() => {
    // 组件挂载时注册监听
    const subscription = Linking.addEventListener('url', ({ url }) => {
      urlChangeHandler(url);
    });

    // 组件卸载时移除监听
    return () => {
      subscription.remove();
    };
  }, []);

  const buyNowHandler = async () => {
    try {
      // 监听注册完成后再打开浏览器
      await WebBrowser.openBrowserAsync("https://google.com");
    } catch (error) {
      console.log(error);
    }
  };

  const urlChangeHandler = (url) => {
    console.log("收到回调url: ", url);
    WebBrowser.dismissBrowser();
  };

  // 其余组件逻辑
}
注意事项

如果你需要获取内置浏览器内部每一次页面跳转的记录,expo-web-browser 不支持该能力,可以改用react-native-webview自行封装自定义内置浏览器,通过onNavigationStateChange属性即可监听所有页面跳转事件。

内容的提问来源于stack exchange,提问作者AndroidDude123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:15:02