Сброс стека навигации для главного экрана (React Navigation and React Native)

У меня проблема с навигацией React Navigation и React Native. Речь идет о сбросе навигации и возврате на главный экран.

Я построил StackNavigator внутри DrawerNavigator, и работает работа между основным экраном и другими экранами. Но проблема в том, что стек навигации растет и растет. Я не уверен, как удалить экран из стека.

Например, при переходе с главного экрана на экран настроек, затем на экран ввода и, наконец, на главный экран, главный экран дважды находится в стеке. С помощью кнопки "Назад" я не выхожу из приложения, но снова на экран ввода.

При повторном выборе домашней кнопки reset в стеке будет отлично, но я не знаю, как это сделать. Здесь кто-то пытался помочь другому человеку с аналогичной проблемой, но решение не сработало для меня.

const Stack = StackNavigator({
  Home: {
    screen: Home
  },
  Entry: {
    screen: Entry
  },
  Settings: {
    screen: Settings
  }
})

export const Drawer = DrawerNavigator({
  Home: {
    screen: Stack
  }},
  {
    contentComponent: HamburgerMenu
  }
)

И это простой пример экрана ящика

export default class HamburgerMenu extends Component {
  render () {
    return <ScrollView>
      <Icon.Button
        name={'home'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Home')}}>
        <Text>{I18n.t('home')}</Text>
      </Icon.Button>

      <Icon.Button
        name={'settings'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Settings')}}>
        <Text>{I18n.t('settings')}</Text>
      </Icon.Button>

      <Icon.Button
        name={'entry'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Entry')}}>
        <Text>{I18n.t('entry')}</Text>
      </Icon.Button>
    </ScrollView>
  }
}

Надеюсь, ты поможешь мне. Это важная часть навигации, и решение будет замечательным!

Ответ 1

Вот как я это делаю:

reset(){
    return this.props
               .navigation
               .dispatch(NavigationActions.reset(
                 {
                    index: 0,
                    actions: [
                      NavigationActions.navigate({ routeName: 'Menu'})
                    ]
                  }));
  }

как минимум замените "Меню" на "Домой". Вы также можете адаптировать this.props.navigation для своей реализации.

In version > 2 follow this:

import { NavigationActions, StackActions } from 'react-navigation';
        const resetAction = StackActions.reset({
                index: 0,
                actions: [NavigationActions.navigate({ routeName: 'MainActivity' })],
            });

this.props.navigation.dispatch(resetAction); 

Ответ 2

Вот как я это делаю:

import { NavigationActions } from 'react-navigation'

this.props.navigation.dispatch(NavigationActions.reset({
    index: 0,
    key: null,
    actions: [NavigationActions.navigate({ routeName: 'ParentStackScreen' })]
}))

Важной частью является key: null.

Это стирает стек при переходе от дочернего навигатора к родительскому навигатору.

Сделайте это, если вы получите эту ошибку:

enter image description here

Для анимации я использую

// https://github.com/oblador/react-native-animatable
import * as Animatable from 'react-native-animatable'

Я просто контролирую все анимации сам. Поместите их в любой компонент, который хотите, обернув его <Animatable.View>.

Ответ 3

Для новейших версий реагирования-навигации вы должны использовать StackActions для сброса стека, вот фрагмент кода:

// import the following
import { NavigationActions, StackActions } from 'react-navigation'

// at some point in your code
resetStack = () => {
 this.props
   .navigation
   .dispatch(StackActions.reset({
     index: 0,
     actions: [
       NavigationActions.navigate({
         routeName: 'Home',
         params: { someParams: 'parameters goes here...' },
       }),
     ],
   }))
}

Ответ 4

Чтобы использовать Назад, вам нужно найти уникальный ключ, связанный с этим путем. Внутри вашего навигационного редуктора вы можете выполнить поиск в существующем состоянии, чтобы найти первый маршрут в стеке, используя этот путь, захватить его ключ и передать его на Назад. Назад затем перейдет к экрану до того, как вы указали путь.

  let key;

  if (action.payload) {
    // find first key associated with the route
    const route = action.payload;

    const routeObj = state.routes.find( (r) => r.routeName === route );

    if (routeObj) {
      key = { key: routeObj.key };
    }
  }

  return AppNavigator.router.getStateForAction( NavigationActions.back( key ), state );

Ответ 5

Ответ - createSwitchNavigator, если он не складывает вашу навигацию. Добавьте свой экран аутентификации/навигатор в createSwitchNavigator с домашним экраном/стеком.

При этом, когда вы переходите из дома для входа в систему, стеки не сохраняются.

Подробнее об этом https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack

Ответ 6

В вашем StackNavigator и DrawerNavigator вы использовали Home как ключ, и я думаю, что он должен быть уникальным и почему он создает проблему. Не могли бы вы попробовать заменить Home на Stack внутри вашего DrawerNavigator.

Надеюсь, это поможет:)

Ответ 7

Действие pop возвращает вас к предыдущему экрану в стеке. Параметр n позволяет указать, сколько экранов будет отображаться.

n - число - количество экранов, чтобы вернуться назад.

импортировать {StackActions} из "реакции-навигации";

const popAction = StackActions.pop({n: 1,});

this.props.navigation.dispatch(popAction);

Ответ 8

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

добавьте это в свойства boxNavigator: unmountInactiveRoutes: true

следует примеру моего кода:

const drawMenu = createDrawerNavigator({
   StackHome,
   StackOS
},{
   unmountInactiveRoutes: true,
   initialRouteName: 'StackHome'
  }
);