Я использую 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'
}
);



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я нашел решение, но оно не идеально.
Вы можете использовать popToTop, который вернется к первой сцене вашего стека, а затем goBack закроет модальное окно.
navigation.popToTop();
navigation.goBack(null);
Проблема в том, что он снова смонтирует первую сцену стека, поэтому убедитесь, что вы не используете setState в willMount или didMount. Или предотвратить это.
Это решение, к которому я сейчас прибегаю. Я продолжаю искать лучшее решение.
Я сам пытался понять это, и решение, которое я в итоге использовал, заключалось в использовании navigation.navigate().
Пример this.props.navigation.navigate('name of screen you want to go');
Надеюсь это поможет!
Оригинальное решение от 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 на ваших экранах, чтобы закрыть модальный стек.Что касается реакции-навигации @ 4, мне удалось вызвать в this.props.screenProps.dismiss().
Простое и удобное решение для 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.
Спасибо :) Я оставил устаревшую навигацию React, но сохраню ее для следующего обхода.