возврат к определенному экрану вместо первого экрана react-native-navigation

#javascript #react-native #react-navigation

#javascript #реагировать-родной #react-навигация

Вопрос:

Когда я нажимаю кнопку «Назад» или выполняю this.props.navigation.goBack() , я возвращаюсь к своему первому экрану вместо первого экрана.

вот мой App.js был ли реализован мой навигатор:

 export default class App extends React.Component {
  render() {
      const MainNavigator = createAppContainer(createBottomTabNavigator({
          info: {
          screen: CtrlInfoStart,
          navigationOptions: { tabBarVisible: false }
      },
          mascotChoice: {
          screen: CtrlMascotChoice,
          navigationOptions: { tabBarVisible: false }
      },
          optionScreen: {
          screen: CtrlOptions,
          navigationOptions: { tabBarVisible: false }
      },
          welcomeScreen: {
          screen: CtrlWelcome,
          navigationOptions: { tabBarVisible: false }
      },
          preview: {
          screen: CtrlPreviewMap,
          navigationOptions: { tabBarVisible: false }
      },
          map: {
          screen: CtrlMap,
          navigationOptions: { tabBarVisible: false }
      },
          pointOfInterest: {
          screen: CtrlPI,
          navigationOptions: { tabBarVisible: false }
      },
          quizz: {
          screen: CtrlQuizz,
          navigationOptions: { tabBarVisible: false }
      }
      }));

    return (
    <View style={styles.container}>
        <MainNavigator/>
    </View>
    );
  }
};
 

Я использую this.props.navigation.navigate('SomeScreen'); для навигации между экранами и this.props.navigation.goBack() для возврата назад.

Ответ №1:

Импорт BackHandler из react native,

в componentdidmount backhandler событии привязки с использованием BackHandler.addEventListner()

смотрите это,

 componentDidmount=()=>{
    BackHandler.addEventListener("hardwareBackPress", this.handleBackButton);
}

componentWillUnmount = () => {
    BackHandler.removeEventListener("hardwareBackPress", this.handleBackButton);
};

  handleBackButton = () => {
    this.props.navigation.navigate('SomeScreen');
    return true;
  };
 

И везде, где вы использовали goBack() , измените его с помощью navigate("ScreenName")

Редактировать:

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

 import {NavigationEvents} "react-navigation";
 

при рендеринге внутри первого компонента,

 <NavigationEvents onWillFocus={this.compnentDidmount} onWillBlur={this.componentWillUnmount} />
 

если у вас есть другая логика в didmount и unmount, создайте отдельные методы для обоих и привяжите NavigationEvents

Комментарии:

1. Спасибо вам! Это работает, хороший взлом. 🙂 Для чего используется ‘return true’ и что он делает?

2. если ничего не возвращено или возвращено false, будет запущена обычная функция кнопки возврата, а не та, которую вы закодировали в методе. Это полезно, если у вас есть условное поведение кнопки возврата.

3. В вашем решении есть одна проблема. Текущий компонент не отключается, когда я выполняю ‘this.props.navigation.navigate(‘SomeScreen’);’ , поэтому метод componentWillUnmount не выполняется. Это вызывает странное поведение, если я переключаюсь между разными экранами.

4. если, например, у меня есть экраны a, b, c и d. Навигация должна быть a-> b, b-> c, b-> d, b<-d, a<-c. Если я перейду на a, b и c, я вернусь к a (пока нормально), затем a-> b, b-> d, d-> b (пока нормально), но если я перейду на c, когда я вернусь, я вернусь к b вместоa. Потому что последний EventListener не был удален, а новый не добавлен.

5. У меня есть эта ошибка: Инвариантное нарушение: Инвариантное нарушение: недопустимый тип элемента: ожидал строку (для встроенных компонентов) или класс / функцию (для составных компонентов), но получил: объект. Проверьте метод визуализации CtrlWelcome .

Ответ №2:

Я нашел решение. Вот мой код :

      export default class App extends React.Component {

      render() {
        return <AppContainer />;
      }
    };

    const stackMapPI = createStackNavigator({
        Map: {
            screen: CtrlMap,
            navigationOptions: () => ({
                header: null
            })
        },
        PI: {
            screen: MainCtrlPIQuizz,
            navigationOptions: () => ({
                header: null
            })
        }

    });

    const stackNav = createStackNavigator({
        Welcome: {
            screen: MainCtrlWelcome,
            navigationOptions: () => ({
                header: null
            })
        },
        Option: {
            screen: CtrlOptions,
            navigationOptions: () => ({
                header: null
            })
        },
        Map: {
            screen: stackMapPI,
            navigationOptions: () => ({
                header: null
            })
        }
    });

const AppContainer = createAppContainer(stackNav);