如何关闭包含多个屏幕的 React Navigation 模式

IT技术 javascript reactjs react-native react-navigation
2021-04-29 21:50:09

我正在使用https://reactnavigation.org/在 React Native 应用程序中导航,其中一个选项卡导航器作为主堆栈和一个带有两个屏幕的模式(用于登录和配置应用程序)。

我一生都无法弄清楚如何从第二个屏幕 ( 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'
  }
);
4个回答

我找到了一个解决方案,但它并不完美。

您可以使用 popToTop 返回到堆栈的第一个场景,然后 goBack 将关闭模式。

navigation.popToTop();
navigation.goBack(null);

这样做的问题是它会再次挂载堆栈的第一个场景,因此请确保不要setState在 willMount 或 didMount 中使用。或者阻止它。

这就是我现在要使用的解决方案。我一直在寻找更好的解决方案。

react-navigation 5.x 简单易用的解决方案

navigation.dangerouslyGetParent()?.goBack();

这是有效的,因为它抓住了导航器的父级,这是模态和您想要关闭的。

从 react-navigation 的文档来看,它实际上并不危险:

该函数被称为危险的GetParent 的原因是警告开发人员不要过度使用它,例如。获取父级的父级和其他难以遵循的模式。

来自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;
};

用法:

  1. 创建您的堆栈:
// modal with two screens
const Setup = StackNavigator(
  {
    Login: Login,
    SelectItems: SelectItems
  },
  {
    initialRouteName: 'Login'
    headerMode: 'none'
  }
);
  1. 调用navigation.dismiss您的屏幕以关闭模态堆栈。

如果您使用 react-navigation 4.x,则有一个方法navigation.dismiss()该方法解散整个堆栈并返回到父堆栈

https://reactnavigation.org/docs/4.x/navigation-prop/#dismiss