reactjsreact-nativereact-navigationreact-navigation-drawer

How to reset navigation history in React Native app


App details:

Issue:

Component ScreenWrapper only contains some buttons that should be rendered on every screen.

Code:

const Content = (props) => {

  const changeScreen = useCallback(
    (screen) => {
      const currentScreenIndex = props.state.index;
      const routes = props.state.routes;
      const currentScreen = routes[currentScreenIndex];
      if (currentScreen.name !== screen) {
        props.navigation.dispatch(
          CommonActions.reset({
            index: 0,
            routes: [{ name: screen }],
            key: null,
          })
        );
      } else {
        props.navigation.closeDrawer();
      }
    },
    [props]
  );

  const menuItems = [
    { title: "Screen1", onPress: () => changeScreen("Screen1") },
    { title: "Screen2", onPress: () => changeScreen("Screen2") },

  return (
    <View style={styles.menuContainer}>
      <Menu items={menuItems} />
    </View>
  )
}

export const DrawerMenu = () => {

  return (
    <NavigationContainer>
      <Drawer.Navigator
        drawerContent={(props) => (
          <Content {...props} />
        )}
        screenOptions={{
          headerShown: false,
          drawerPosition: "right",
        }}
        initialRouteName="Screen1"
      >
        <Drawer.Screen name="Screen1">
          {(props) => (
            <ScreenWrapper {...props}>
              <Screen1 {...props} />
            </ScreenWrapper>
          )}
        </Drawer.Screen>
        <Drawer.Screen name="Screen2">
          {(props) => (
            <ScreenWrapper {...props}>
              <Screen2 {...props} />
            </ScreenWrapper>
          )}
        </Drawer.Screen>
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

Output when printing props.state.history inside <Content />:

 [
      {
        "type": "route",
        "key": "Screen1-PLBmP7u8v6S1WbEGAukrA"
      },
      {
        "type": "route",
        "key": "Screen2-yIKWpqea5G7UQXcpIfqK9"
      }
    ]

Screen1 is the landing screen that seems that is not being removed on reset.


Solution

  • Add backBehavior: "none" to Drawer.Navigator

    Update changeScreen() function to use jumpTo()