1

I have 3 screens. A=>Login, B=>Dashboard, C=>Profile.

Initially when user is not logged in the Login screen renders. After login I have used AsyncStorage to save userId(which i get from API response). If user is logged in already and opens the application, I have redirected user to Dashboard page.

These are the problems i am facing with my code implementation.

  1. after login, if user press the back button on Dashboard page(Andriod), it navigates back to the login screen. and this time componentDidMount() method does not invoked so i am unable to put a check if the user has came from dashboard screen.
  2. I have tried to register BackHandler event on Dashboard's componentDinMount() method with condition => if user press back button, the application will exit, but problem is I am unable to remove this event on the same screen, so if I go to Profile screen from Dashboard, and from Profile page if i press backbutton, the application exits.

All I want to achieve is, After login, until the user presses logout button, user should not be able to go login screen.

Anukool
  • 732
  • 1
  • 9
  • 21
  • Possible duplicate of [React Native - Device back button handling](https://stackoverflow.com/questions/45031085/react-native-device-back-button-handling) – FreakyCoder Nov 12 '19 at 07:55

7 Answers7

2

You need to reset your navigation history to do that

This is a snippet from one of my project where I needed to do the same:

this.props.navigation.reset([NavigationActions.navigate({ routeName: 'DevicesList'})], 0);
2

You can simply achieve this by using switch navigator instead of a stack navigator when navigating from 'Login screen' to 'Dashboard'.

const MainStack = createStackNavigator({
    DashboardScreen: Dashboard,
    ProfileScreen: Profile
});

export default createAppContainer(createSwitchNavigator({
  LoginScreen: Login,
  Main: MainStack
}));
Awab Ijaz
  • 101
  • 5
1

This will disable device's back button

import { BackHandler } from "react-native";

const Dashboard = () => {
    useEffect(() => {
        const handleBackButton = () => true;
        BackHandler.addEventListener("hardwareBackPress", handleBackButton);
        return () => {
            BackHandler.removeEventListener(
                "hardwareBackPress",
                handleBackButton
            );
        };
    }, []);
    
    return (
        // code
    )
}

Source

Zahir Masoodi
  • 546
  • 7
  • 23
0

For this i would suggest using a SwitchNavigator (if using react-navigation). This will let the previous screen (in this case your LoginScreen) unmount and you'll not be able to goBack to that screen, unless you explicity tell it to navigate to the screen.

If not, you can still use your custom backHandling in your DashBoard screen, and use the react-navigaton withNavigationFocus HOC.

The componentDidMount will stay the same as your first attempt. You'd need to use componentDidUpdate and check for the isFocused prop, like:

componentDidUpdate = prevProps => {
   if (prevProps.isFocused !== this.props.isFocused) {
        this.props.isFocused ? this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress) :
        this.backHandler.remove()
   }
}

Let me know if you are having a problem with one of the solutions

Auticcat
  • 4,359
  • 2
  • 13
  • 28
0

React Navigation v5 documentation cover this use case. documentation link

umar zahir
  • 19
  • 3
0

To restrict user from going back to login screen after successful login , use navigation.replace(). To be precise, make 2 different stack navigators; One for Onboarding and Sign in/Sign up and second for app screens.

Then after singing is completed run navigation.replace() instead of navigation.navigate().

This will remove or detach the previous navigator with the whole route nest until it is logged Out. And also at log out use the same concept to redirect user to login screen.

0

Here's an example using StackActions and the useNavigation hook

// Navigation index
export default function AppNavigation() {
  const Stack = createStackNavigator();
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Login"
        screenOptions={{headerShown: false}}>
        <Stack.Screen name="Login" component={Login} />
        <Stack.Screen name="App" component={MainNavigator} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

// Login
export default function Login() {
    const navigation = useNavigation();
    useEffect(() => {
        // Authenticate the user input
        if (authenticate(input)) {
            navigation.dispatch(StackActions.replace('App'));
        }
    }, [...])
    ...
}
Echo
  • 521
  • 5
  • 16