【问题标题】:How to close a React Navigation modal with multiple screens in it如何关闭其中包含多个屏幕的 React Navigation 模式
【发布时间】: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'
  }
);

【问题讨论】:

    标签: javascript reactjs react-native react-navigation


    【解决方案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;
      };
      

      用法:

      1. 创建堆栈:
      // modal with two screens
      const Setup = StackNavigator(
        {
          Login: Login,
          SelectItems: SelectItems
        },
        {
          initialRouteName: 'Login'
          headerMode: 'none'
        }
      );
      
      1. 在屏幕中调用 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 年使用钩子
      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      相关资源
      最近更新 更多