如何关闭其中包含多个屏幕的 React Navigation 模式
Posted
技术标签:
【中文标题】如何关闭其中包含多个屏幕的 React Navigation 模式【英文标题】:How to close a React Navigation modal with multiple screens in it 【发布时间】:2018-09-23 01:35:01 【问题描述】:我在 React Native 应用程序中使用 https://reactnavigation.org/ 进行导航,其中一个选项卡导航器作为主堆栈,一个包含两个屏幕的模式(用于登录和配置应用程序)。
我一辈子都想不出如何从第二个屏幕关闭模式 (SelectItems
)。从模式中的第一个屏幕,我可以用navigation.goBack()
关闭它。
两个模态屏幕都需要一个关闭按钮。有没有办法返回到用户所在的任何选项卡?
提前感谢您的帮助。
const Tabs = TabNavigator(
Search: screen: Search ,
Settings: screen: Settings
);
// modal with two screens
const Setup = StackNavigator(
Login:
screen: Login
,
SelectItems:
screen: SelectItems
,
initialRouteName: 'Login'
);
const RootStack = StackNavigator(
Main:
screen: Tabs
,
Setup:
screen: Setup
,
mode: 'modal',
headerMode: 'none'
);
【问题讨论】:
【参考方案1】:我找到了解决方案,但并不完美。
您可以使用 popToTop 将返回到堆栈的第一个场景,然后 goBack 将关闭模式。
navigation.popToTop();
navigation.goBack(null);
这样做的问题是它会再次挂载堆栈的第一个场景,所以请确保不要在 willMount 或 didMount 中使用setState
。或者阻止它。
这就是我现在要使用的解决方案。我一直在寻找更好的解决方案。
【讨论】:
现在有更好的解决方案吗?【参考方案2】:简单易用的 react-navigation 5.x 解决方案(getParent docs):
navigation.getParent()?.goBack();
之所以有效,是因为它抓取了导航器的父级,即模式和您想要关闭的内容。
注意:在旧版本的 5.x 中,这称为dangerouslyGetParent
。这存在于较新的 5.x 版本中,但现在已弃用。如果 getParent
在您使用的 react-navigation 版本中不可用,请使用它。它实际上并不危险:来自 react-navigation 的文档:
该函数被称为危险GetParent 的原因是警告开发人员不要过度使用它,例如。获取 parent 的 parent 和其他难以遵循的模式。
【讨论】:
这解决了我的问题,非常感谢。我已经为此苦苦挣扎了至少2个小时。我遇到了一个问题,我会从堆栈上的父导航器推送屏幕,然后当我返回时,当前堆栈将导航回来,但最新推送的屏幕(来自父堆栈)将保持可见。快把我逼疯了。谢谢!!【参考方案3】:如果你使用 react-navigation 4.x 有一个方法navigation.dismiss()
。该方法关闭整个堆栈并返回父堆栈
https://reactnavigation.org/docs/4.x/navigation-prop/#dismiss
【讨论】:
【参考方案4】:来自https://github.com/react-navigation/react-navigation/issues/686#issuecomment-342766039 的原始解决方案,针对 React Navigation 4 进行了更新:
创建DismissableStackNavigator
:
import React from 'react';
import createStackNavigator from 'react-navigation-stack';
export default function DismissableStackNavigator(routes, options)
const StackNav = createStackNavigator(routes, options);
const DismissableStackNav = (navigation, screenProps) =>
const state, goBack = navigation;
const props =
...screenProps,
dismiss: () => goBack(state.key),
;
return (
<StackNav
screenProps=props
navigation=navigation
/>
);
DismissableStackNav.router = StackNav.router;
return DismissableStackNav;
;
用法:
-
创建堆栈:
// modal with two screens
const Setup = StackNavigator(
Login: Login,
SelectItems: SelectItems
,
initialRouteName: 'Login'
headerMode: 'none'
);
-
在屏幕中调用
navigation.dismiss
以关闭模式堆栈。
【讨论】:
从 react-navigation@4 开始,我设法打电话给this.props.screenProps.dismiss()
【参考方案5】:
我试图自己解决这个问题,我最终使用的解决方案是使用navigation.navigate()
例如this.props.navigation.navigate('name of screen you want to go');
希望这会有所帮助!
【讨论】:
谢谢 :) 我坚持使用已弃用的 React 导航,但我将其保存以备下次使用。 这个答案已经过时了,你需要在 2021 年使用钩子以上是关于如何关闭其中包含多个屏幕的 React Navigation 模式的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React Native 中使 Tab.Navigation Screens 默认背景为白色?
如何使用 createStackNavigator 将 createBottomTabNavigator 添加到同一屏幕