Реагирование на странное поведение кнопок навигации во вложенных навигаторах

Я использую React Navigation в своем приложении, и у меня есть Tab Navigator, вложенный в Stack Navigator. Иногда в приложении стек навигации:

Экран A => Навигатор по вкладкам => Экран B.

Поэтому, когда пользователи находятся на экране B и нажимают кнопку "Назад", сначала запускается обратное действие в навигаторе вкладок, и только если в Навигаторе вкладок нет действия goBack, запускается действие goBack с экрана B.

Таким образом, пользователь получает неожиданное поведение, когда он находится на экране B и перемещается между вкладками. Пользователь продолжает нажимать кнопку "Назад" до тех пор, пока "Навигатор вкладок" не вернется к первой вкладке, и только затем, после другого нажатия кнопки "Назад", он перейдет с экрана B обратно на вкладки.

Могу ли я в любом случае архивировать ожидаемое поведение в этом случае?

Ответ 1

Вы правильно обрабатываете кнопку возврата? на каждом компоненте верхнего уровня контейнера нужно обрабатывать нажатие кнопки "назад", например:

import * as React from 'react';
import { BackHandler } from 'react-native';

export default MyComponent extends React.Component<any, any> {
  public componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.goBack);
  }

  public componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.goBack);
  }

  private goBack = () => {
    this.props.navigation.goBack();
    return true;
  }
}

Возвращая true, вы останавливаете каскадирование распространения нажатия кнопки "Назад" в предыдущие контейнеры.

Ответ 2

Если я правильно понимаю ваши настройки, я думаю, что вы хотите установить backBehavior: 'none' в TabNavigatorConfig. Это предотвратит перемещение вкладок истории состояний.

Например:

const MyTabNav = createBottomTabNavigator({
  ScreenOne: ScreenOne,
  ...
}, {
  backBehavior: 'none', // <-- Here
  initialRouteName: 'ScreenOne',
  tabBarOptions: {
    ...
  }
})

Если это не совсем то, что вы хотите, вы можете попробовать поиграть с другими поведениями спины. Два новых поведения были добавлены в версии 3.2.0 (см. Https://github.com/react-navigation/rfcs/blob/master/text/0008-back-behaviour-for-tabs.md).

Ответ 3

Вы можете обработать это, используя событие BackHandler на странице TabNavigator.

componentDidMount() {
    if ("android" === Platform.OS) {
      BackHandler.addEventListener("hardwareBackPress", this.handleBackPress);
    }
  }

  componentWillUnmount() {
    if ("android" === Platform.OS) {
      BackHandler.removeEventListener(
        "hardwareBackPress",
        this.handleBackPress
      );
    }
  }
  handleBackPress = () => {
    if (this.props.navigation.isFocused()) {
      this.navigateBack();
    } else {      
      this.props.navigation.goBack(null);
    }
    return true;
  };

Когда аппаратная кнопка возврата нажата на экране B, будет вызван метод обратной обработки на вкладке, и поток будет работать правильно.

Но у меня есть проблема в другом сценарии.

У меня есть следующий рабочий процесс.

Навигатор вкладок A → Навигатор вкладок B → Экран

При нажатии кнопки "Назад" на экране проблема сохраняется.

Ответ 4

Любая душа. У меня такая же проблема