-->

react-navigation 3 reset in nested stack

2020-02-14 03:10发布

问题:

Im try to understand how to reset in nested stack this my code

    const AuthStack = createStackNavigator(
      {
        Welcome,
        Login,
        Register,
        ConfirmationCode,
      },
      {
        initialRouteName: 'Welcome',
        headerMode: 'none',
        lazy: true,
        transitionConfig,
        defaultNavigationOptions: {
          gesturesEnabled: false,
        },
      }
    )

    const AppStack = createStackNavigator(
      {
        TabStack,
        SearchResult,
        BusinessDetail,
        BusinessMap,
        MakeAppointment,
        TermsAndConditions
      },
      {
        initialRouteName: 'TabStack',
        headerMode: 'none',
        lazy: true,
        transitionConfig,
        defaultNavigationOptions: {
          gesturesEnabled: false,
        },
      }
    )

    let MainStack = createSwitchNavigator(
      {
        AuthLoading,
        Auth: AuthStack,
        App: AppStack,
      },
      {
        initialRouteName: 'AuthLoading',
        headerMode: 'none',
        lazy: true,

        defaultNavigationOptions: {
          gesturesEnabled: false,
        },
      }
    )

TabStack

    import React from 'react';

    import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
    import {
        Search,
        MyFavourites,
        MyAppointments,
        UserProfile
    } from '../screens'
    import Icon from 'react-native-vector-icons/Feather';
    import Colors from '../utils/Colors'
    let TabStack = createBottomTabNavigator(
      {
        Search,
         MyFavourites,
         MyAppointments,
         UserProfile,
      },
        initialRouteName: 'ScreenTab1',
        tabBarOptions: {
          activeTintColor: Colors.pink,
          inactiveTintColor: Colors.black,
          showLabel: false,
          style: {
            backgroundColor: 'white'
          }
        },
      }
    )
    export default createAppContainer(TabStack);

I want to understand how to make reset for example:

    reset from UserProfile to TabStack (in AppStack) to AuthStack

I tried to do from it this way

const resetAction = StackActions.reset({
        index: 0,
        actions: [NavigationActions.navigate({ routeName: 'AuthStack' })],
    });
    this.props.navigation.dispatch(resetAction);

or this way

const resetAction = StackActions.reset({
        index: 0,
        key: null,
        actions: [NavigationActions.navigate({ routeName: 'AuthStack' })],
    });
    this.props.navigation.dispatch(resetAction);

but i got the error

there is no route defined for AuthStack

I checked in issues in stackoverflow but the answers there not works for me,always show me the same error I wrote above.

回答1:

Your resetAction is unsuccessful because you are dispatching it on TabStack (because you are calling this.props.navigation.dispatch on UserProfile, if I get you correctly). You need to dispatch the resetAction to your MainStack instead. This thread here suggested some ways that you can achieve this. And also, here is my preferred solution, because i don't have to pass props around navigators or calls multiple nested actions with this.

  1. Create a navigationService.js with the following contents (to keep your top level navigator as a reference)
import { NavigationActions, StackActions } from 'react-navigation';

let _navigator;

function setTopLevelNavigator(navigatorRef) {
  _navigator = navigatorRef;
}

function navigateMainNavigator(routeName, params) {
  _navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params,
    }),
  );
}

// add other navigation functions that you need and export them

export default {
  setTopLevelNavigator,
  navigateMainNavigator,
};
  1. On your App.js or any other file you render your MainStack, do this to set the reference
import NavigationService from './navigationService';

...

render() {
  return (

    ...
    <MainStack
      ref={navigatorRef => {
        NavigationService.setTopLevelNavigator(navigatorRef);
      }}
    />
    ...

  )
}
  1. And wherever when you want to reset to your AuthStack (or any other stack in your MainStack), just import NavigationService and call
NavigationService.navigateAndReset('Auth', {...yourParamsIfAny});
// 'Auth' because you named it that way in your 'MainStack'

===========================================================================

Edited

Previous solution, in navigationService.js, is for StackNavigator as the MainStack

function navigateAndReset(routeName, params) {
  _navigator.dispatch(
    StackActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({
          routeName,
          params,
        }),
      ],
    })
  );
}


回答2:

Try by setting it to AppStack, because anyhow it is going to redirect to GeneralStack as you have it as initialRouteName inside AppStack

const resetAction = StackActions.reset({
      index: 0,
      key: null,
      actions: [NavigationActions.navigate({ routeName: 'App' })],
    });
    this.props.navigation.dispatch(resetAction);


回答3:

You can do the following, to reset to authStack,

create a reset actions as following,

const resetAction = StackActions.reset({
  index: 0,
  actions: [NavigationActions.navigate({ routeName: "AuthStack" })],
  key: null
});
this.props.navigation.dispatch(resetAction);

and also add the AuthStack into appStack, or the stack from which you are calling the above code.

For example if your calling this from your appstack, add the following line as a route within your app stack

  const AppStack = createStackNavigator(
  {
    TabStack,
    SearchResult,
    BusinessDetail,
    BusinessMap,
    MakeAppointment,
    TermsAndConditions,
    AuthStack <---Insert THIS
  },

This works for me when using to signout.