React Native DrawerNavigator打开Facebook页面后返回异常的修复方案
这个问题的核心是你把跳转逻辑放在了screen的位置,而不是用正确的导航选项来处理,导致导航栈里多了一个空页面,返回时先落到这个空白页,才回到主页。我来帮你解决这个问题:
首先,先分析你当前写法的问题:
你给FacebookPage的screen赋值了一个返回null的函数,这相当于在导航栈中添加了一个没有任何内容的页面。当你打开Facebook后返回,首先回到这个空页面,所以需要再点一次返回才能回到Home,同时这个空页面不符合React Navigation对screen的组件要求,还会抛出错误。
接下来是两种解决方法,推荐第一种:
方法一:直接在导航选项的onPress中处理跳转(最优解)
我们不需要给FacebookPage设置实际的页面,而是在点击Drawer选项时直接执行跳转逻辑,这样不会往导航栈里添加任何额外页面,返回时直接回到原来的页面。
步骤如下:
- 先定义一个空组件(因为DrawerNavigator的路由必须有
screen,但我们不会用到它):
const EmptyScreen = () => null;
- 修改
DrawerNavigator中FacebookPage的配置:
FacebookPage: { screen: EmptyScreen, navigationOptions: { drawerLabel: 'Facebook', onPress: () => { // 尝试打开Facebook App,失败则打开网页版 Linking.canOpenURL('fb://page/1000000000') .then((supported) => { if (supported) { Linking.openURL('fb://page/1000000000'); } else { Linking.openURL('http://facebook.com/1000000000/'); } }) .catch(err => Alert.alert('跳转失败', err.toString())); }, }, },
这样点击Drawer里的Facebook选项时,直接触发跳转,不会产生额外的页面,从Facebook返回后就直接回到之前的页面(比如Home),不会有空白页和错误。
方法二:创建跳转专用组件(备选方案)
如果你更倾向于用组件的方式处理,可以创建一个专门的跳转组件,在组件挂载时执行跳转,然后立即返回上一页:
- 创建跳转组件:
import React, { useEffect } from 'react'; import { Linking, Alert } from 'react-native'; const FacebookRedirectScreen = ({ navigation }) => { useEffect(() => { const handleRedirect = async () => { try { const supported = await Linking.canOpenURL('fb://page/1000000000'); if (supported) { await Linking.openURL('fb://page/1000000000'); } else { await Linking.openURL('http://facebook.com/1000000000/'); } } catch (err) { Alert.alert('跳转失败', err.toString()); } finally { // 跳转完成后立刻返回上一页,避免栈中留下空页面 navigation.goBack(); } }; handleRedirect(); }, [navigation]); // 可以在这里返回一个加载指示器,避免短暂的空白 return null; };
- 在
DrawerNavigator中使用这个组件:
FacebookPage: { screen: FacebookRedirectScreen, navigationOptions: { drawerLabel: 'Facebook', }, },
这种方式下,点击选项后会短暂导航到这个组件,执行跳转后立刻返回,所以返回时也不会有空白页问题。
修改后的完整代码示例(方法一)
import React, { Component } from 'react'; import { DrawerNavigator } from 'react-navigation'; import { Linking, Alert } from 'react-native'; import HomeScreen from './HomeScreen'; // 你的Home组件 import MyAccountScreen from './MyAccountScreen'; // 你的账户组件 const EmptyScreen = () => null; class Root extends Component { render() { const Drawer = DrawerNavigator( { Home: { screen: HomeScreen, navigationOptions: { drawerLabel: 'home', }, }, FacebookPage: { screen: EmptyScreen, navigationOptions: { drawerLabel: 'Facebook', onPress: () => { Linking.canOpenURL('fb://page/1000000000') .then((supported) => { if (supported) { Linking.openURL('fb://page/1000000000'); } else { Linking.openURL('http://facebook.com/1000000000/'); } }) .catch((err) => Alert.alert('跳转失败', err.toString())); }, }, }, MyAccount: { screen: MyAccountScreen, navigationOptions: { drawerLabel: 'My account', }, }, }, { initialRouteName: 'Home', } ); return <Drawer />; } } export default Root;
这样修改后,返回时就不会有错误和空白页的问题了。
内容的提问来源于stack exchange,提问作者Idan
相关产品推荐
相关产品推荐

