6

I would like after Login (Welcome) the user to navigate to Home. I reset the history so the user cannot go back like this:

const actionToDispatch = NavigationActions.reset({
            index: 0,
            actions: [NavigationActions.navigate({ routeName: 'Home' })]
        });

        this.props.navigation.dispatch(actionToDispatch);

This works properly. After pressing Log Out the user should go back to Welcome but it's not working. Here's what exactly I am doing:

const resetAction = NavigationActions.reset({
            index: 0,
            actions: [
                NavigationActions.navigate({ routeName: 'Welcome' }),
            ]
        });

        this.props.navigation.dispatch(resetAction);

The error says that there is no route for 'Welcome'. Must be one of 'Main', 'Privacy', 'Terms' which are routes of one of the tabs in the Home. See them below:

 const AppStack = StackNavigator({
                    Welcome: {
                        screen: Welcome
                    },
                    Home: {
                        screen: Tabs
                    }
                }, {
                        initialRouteName: this.state.isLoggedIn ? 'Home' : 'Welcome',
                        headerMode: 'none'
                    }
                );

export const ProfileStack = StackNavigator({
    Profile: {
        screen: Profile,
    },
});

export const SettingsStack = StackNavigator({
    Settings: {
        screen: Settings,
    },
}, {
    });

export const InfoStack = StackNavigator({
    Main: {
        screen: Main,
    },
    Privacy: {
        screen: Privacy
    },
    Terms: {
        screen: Terms
    }
});

const routeConfiguration = {

    Profile: { screen: ProfileStack },
    Settings: { screen: SettingsStack },
    Info: { screen: InfoStack }
};

const tabBarConfiguration = {
    tabBarOptions: {
        activeTintColor: 'white',
        inactiveTintColor: 'lightgray',
        labelStyle: {
            fontSize: Normalize(10),
            fontFamily: Fonts.book
        },
        style: {
            backgroundColor: Colors.greenLightGradient,
            borderTopWidth: 1,
            borderTopColor: Colors.tabGreenLine
        },
    }
};

export const Tabs = TabNavigator(routeConfiguration, tabBarConfiguration);
vaklinzi
  • 1,913
  • 2
  • 18
  • 30

4 Answers4

15

I found the solution here: https://github.com/react-community/react-navigation/pull/789.

const resetAction = NavigationActions.reset({
            index: 0,
            actions: [
                NavigationActions.navigate({ routeName: 'Welcome' }),
            ],
            key: null
        });

this.props.navigation.dispatch(resetAction);

key: null is the important part.

David Schumann
  • 13,380
  • 9
  • 75
  • 96
vaklinzi
  • 1,913
  • 2
  • 18
  • 30
  • 1
    I've the same code but it's not working for me. Does this only work on StackNavigator? I'm using the TabNavigator. – Tom Spee Aug 07 '17 at 10:06
  • Yes, I think that it's not working for TabNavigator. But you should check again because it was several months ago when I lastly check for this. – vaklinzi Aug 07 '17 at 10:17
  • I also found that this doesn't work for me, created a question here: https://stackoverflow.com/questions/45575437/react-navigation-preventing-going-back-to-loading-screen?noredirect=1#comment78111975_45575437 – Barry Michael Doyle Aug 08 '17 at 19:28
4

For anyone who is looking for React Navigation 3.x and 4.x solution

import {NavigationActions, StackActions} from 'react-navigation';

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

React Navigation move the reset method to StackActions since 3.x

John Lim
  • 3,019
  • 4
  • 31
  • 41
3

replace home with any screen you want reset history for (v5)

import { CommonActions } from '@react-navigation/native';
  navigation.dispatch(state => {
 // Remove the home route from the stack
 const routes = state.routes.filter(r => r.name !== 'Home');

 return CommonActions.reset({
...state,
routes,
index: routes.length - 1,
});
});
ahmed mersal
  • 167
  • 2
  • 3
0

For those who use version 5.x, Ahmed Mersal's solution is perfect.

Starting from that, we can do a reusable React hook:

import { useNavigation, CommonActions } from "@react-navigation/native";
import { useEffect } from "react";

export const useRemoveRouteFromState = (
  routeName: keyof ReactNavigation.RootParamList
) => {
  const navigation = useNavigation();

  useEffect(() => {
    navigation.dispatch((state) => {
      const routes = state.routes.filter(({ name }) => name !== routeName);

      return CommonActions.reset({
        ...state,
        routes,
        index: routes.length - 1,
      });
    });
  }, [navigation]);
};

Then, inside a component, we just have to use it:

export const PurchaseScreen: React.FC = () => {
  useRemoveRouteFromState('Home');

  // ...
};