Как закрыть модальное окно React Navigation с несколькими экранами

Я использую 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'
  }
);
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
14
0
11 258
4

Ответы 4

Я нашел решение, но оно не идеально.

Вы можете использовать popToTop, который вернется к первой сцене вашего стека, а затем goBack закроет модальное окно.

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

Проблема в том, что он снова смонтирует первую сцену стека, поэтому убедитесь, что вы не используете setState в willMount или didMount. Или предотвратить это.

Это решение, к которому я сейчас прибегаю. Я продолжаю искать лучшее решение.

Я сам пытался понять это, и решение, которое я в итоге использовал, заключалось в использовании navigation.navigate().

Пример this.props.navigation.navigate('name of screen you want to go');

Надеюсь это поможет!

Спасибо :) Я оставил устаревшую навигацию React, но сохраню ее для следующего обхода.

Alex Dunae 21.07.2018 01:42

Оригинальное решение от 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 на ваших экранах, чтобы закрыть модальный стек.

Что касается реакции-навигации @ 4, мне удалось вызвать в this.props.screenProps.dismiss().

Artur Eshenbrener 18.03.2020 16:02

Простое и удобное решение для React-Navigation 5.x

navigation.dangerouslyGetParent()?.goBack();

Это работает, потому что он захватывает родительский элемент навигатора, который является модальным и то, что вы хотите отклонить.

На самом деле это не опасно, из документации response-navigation:

Reason why the function is called dangerouslyGetParent is to warn developers against overusing it to eg. get parent of parent and other hard-to-follow patterns.

Другие вопросы по теме