reactjsreact-nativereact-navigationreact-navigation-stackreact-navigation-v5

How to reset nested navigators (react-navigation v5)


Having two sets of stack navigators;

const SetOneScreens = () => (
  <Stack.Navigator initialRouteName="AScreen">
    <Stack.Screen name="AScreen" component={AScreen} />
    <Stack.Screen name="BScreen" component={BScreen} />
  </Stack.Navigator>
);
const SetTwoScreens = () => (
  <Stack.Navigator initialRouteName="CScreen">
    <Stack.Screen name="CScreen" component={CScreen} />
    <Stack.Screen name="DScreen" component={DScreen} />
  </Stack.Navigator>
);

Which are nested in a Drawer navigator

    <NavigationContainer>
      <Drawer.Navigator initialRouteName="SetOneScreens">
        <Drawer.Screen name="SetOneScreens" component={SetOneScreens} />
        <Drawer.Screen name="SetTwoScreens" component={SetTwoScreens} options={{swipeEnabled: false}} />
      </Drawer.Navigator>
    </NavigationContainer>

I want to navigate From BScreen to DScreen and reset the stack (in order to not letting hardware back button in android get back to BScreen)

As in the nesting situation, we should first define the navigator name; how should I define the screen in reset action.

// For navigation 
props.navigation.navigate('setTwoScreens',{screen:'DScreen'})

// For reset I can only navigate to initial screen 
props.navigation.reset({index:0,routes:[{name:'setTwoScreens'}]})

How should I handle the reset with navigation or CommonActions


Solution

  • As written in the documentation of react-navigation-v5, you need to dispatch CommonAction with reset-action to clear back-stack of your application, so that application doesn't go back to previous screen when user press hardware back-button of device, check below example,

    import { CommonActions } from "@react-navigation/native";
    
    props.navigation.dispatch({
      CommonActions.reset({
        index: 0,
        routes: [{ name: "AnotherStackNavigator" }]
      })
    });
    

    Or if you want to reset to specific screen in that StackNavigator you can do like this:

    props.navigation.dispatch({
      CommonActions.reset({
        index: 0,
        routes: [
          {
            name: "AnotherStackNavigator",
            state: {
              routes: [
                {
                  name: "AnotherStackNavigatorScreen",
                  params: {         
                      ...
                  }
                }
              ]
            }
          }
        ]
      })
    });