Expo开发:如何检测用户主动关闭WebBrowser实例的操作?
解决Expo WebBrowser用户主动关闭未检测导致loading卡死问题
核心思路
- Expo的
WebBrowser.openBrowserAsync是异步方法,返回的Promise会在浏览器实例完全关闭后触发resolve,你可以通过该返回值结合回调标记判断用户是否主动关闭了浏览器 - 需新增回调完成标记,区分「用户主动关闭浏览器」和「3DS跳转触发浏览器关闭」两种场景
修改后完整代码
import React, { FC, useEffect, useState, useRef, } from 'react'; import * as Linking from 'expo-linking'; import * as WebBrowser from 'expo-web-browser'; import { Button, } from '@private/apps-components'; import { ButtonProps, View, } from 'react-native'; export const MyComponent: FC = () => { const [loading, setLoading] = useState<boolean>(false); // 新增ref标记3DS回调是否已处理,区分关闭场景 const isCallbackHandled = useRef<boolean>(false); const urlEventHandler = async (event): Promise<void> => { console.log('url-event', event); // 标记回调已处理 isCallbackHandled.current = true; setLoading(false); // Stuff... }; useEffect(() => { Linking.addEventListener('url', urlEventHandler); return () => Linking.removeEventListener('url', urlEventHandler); }, []); const handlePress: ButtonProps['onPress'] = async () => { // 修复原代码笔误:点击后应开启loading setLoading(true); // 每次点击前重置回调标记 isCallbackHandled.current = false; const result = await WebBrowser.openBrowserAsync(aRandomUrlThatWillRedirectToTheApp, { showInRecents: true, }); // 浏览器关闭后判断:如果回调未处理,说明是用户主动关闭浏览器 if (!isCallbackHandled.current) { setLoading(false); // 可在此处添加用户取消3DS验证的后续逻辑 } } return ( <View> <Button title="Test" onPress={handlePress} loading={loading} /> </View> ); }; export default null;
关键修改说明
- 新增
isCallbackHandledref标记:避免将3DS回调触发的浏览器关闭误判为用户主动关闭 - 等待
openBrowserAsync执行完成:只要浏览器关闭,无论关闭原因都会走到该异步方法的后续逻辑 - 关闭后校验回调状态:如果回调未触发就关闭了浏览器,直接重置loading状态,避免卡死
内容的提问来源于stack exchange,提问作者Soullivaneuh
相关产品推荐
相关产品推荐

