Home > Mobile >  Conditional navigation inside Tabs
Conditional navigation inside Tabs

Time:05-12

i want to show a screen depending on a state. So when I click on the bottom left tab, if there is a valid user, I want to be redirected to the UserProfile-screen, else redirect to the LoginScreen. The react-native navigation confuses me, i just cant see whats wrong. So in LoginRoutes.tsx I just try to change this behaviour by using true / false Thanks in Advance.

What I have so far:

BottomTabBar.tsx:

export const BottomTabNavigator = () => {
  const colorScheme = useColorScheme();
  return (
    <Tab.Navigator
      screenOptions={{
        tabBarShowLabel: true,
        tabBarStyle: {
          backgroundColor: "#292929",
          borderTopWidth:0
        },
        tabBarInactiveTintColor: "#919191",
        tabBarInactiveBackgroundColor: "#292929",
        tabBarActiveTintColor: Colors[colorScheme].text,
        headerShown: false,
      }}
    >
     <Tab.Screen
        name="LoginRoutes"
        component={LoginRoutes}
        options={{ title: "Login", headerShown: false}}
      />

      <Tab.Screen
        name="SettingsTabScreen"
        component={SettingsTabScreen}
        options={{ headerShown: false,title:"test" }}
      />
    </Tab.Navigator>
  );
};

LoginRoutes.tsx

import * as React from "react";
import { ActivityIndicator, View, Text } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { createStackNavigator } from "@react-navigation/stack";
import NavigationContainer from "./UserProfileStack";
import LoginScreen from "../Screens/LoginScreen";
import UserProfile from "../components/UserProfile";
import Colors from "../constants/Colors";
import { UserProfileInfo } from "../constants/Types";

function LoginRoutes({ navigation }: { navigation: any }) {
  const [loading, setLoading] = React.useState(true);
  const [user, setUser] = React.useState(null);

  const Stack = createStackNavigator();

  React.useEffect(() => {
    // check if the user is logged in or not
    AsyncStorage.getItem("user")
      .then((userString) => {
        if (userString) {
          console.log("-----------EXISTING------------");
          console.log(JSON.parse(userString).id);
          setUser(JSON.parse(userString));
        } else {
          console.log("not logged in, showing LoginPage");
        }
        setLoading(false);
      })
      .catch((err) => {
        console.log(err);
        setLoading(false);
      });
  }, []);

  if (loading) {
    return (
      <View
        style={{
          height: "100%",
          justifyContent: "center",
          backgroundColor: Colors.dark.background,
        }}
      >
        <ActivityIndicator
          size="large"
          style={{ backgroundColor: Colors.dark.background }}
        />
        <Text
          style={{
            color: Colors.dark.text,
            marginTop: 10,
            alignSelf: "center",
          }}
        >
          retrieving userdata...
        </Text>
      </View>
    );
  }
  return (
    <NavigationContainer>
      <Stack.Navigator>
        {true ? (
          <Stack.Screen name="LoginScreen" component={LoginScreen} />
        ) : (
          <Stack.Screen name="UserProfile" component={UserProfile} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default LoginRoutes;

The stackNavigator:

import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";


import LoginScreen from "../Screens/LoginScreen";
import UserProfile from "../components/UserProfile";
import { UserProfileInfo } from "../constants/Types";
import { StackNavigationProp } from '@react-navigation/stack';
export type UserProfileStackParams = {
    LoginScreen: undefined, 
    UserProfile: { profileInfo: UserProfileInfo };
  };

const screens = {
  LoginScreen: {
    screen: LoginScreen,
    navigationOptions: {headerShown: false,gestureEnabled:false},
  },
  UserProfile: {
    screen: UserProfile,
    navigationOptions: {headerShown: false,gestureEnabled:false},
  },
};

// home stack navigator screens
const UserProfileStack = createStackNavigator(screens);

export default createAppContainer(UserProfileStack);

UserProfile.tsx


type Props = {
  navigation: StackNavigationProp<UserProfileStackParams, "UserProfile">
  loggedInUser: {}
};


const DATA = [
  {
    // contains valid data
  },
];
  export const UserProfile: React.FC<Props> = ({ navigation}) => {
  const [steamID, setSteamID] = React.useState({ id: null, watchLists: null });
  const [profileInfo, setProfileInfo] = React.useState<UserProfileInfo>(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    // check if the user is logged in or not
    AsyncStorage.getItem("user")
      .then((userString) => {
        if (userString) {
          console.log("logged in.");
          setSteamID(JSON.parse(userString));
          fetchUserProfile(steamID.id).then((response) => {
            setProfileInfo(response);
          });
        } else {
          console.log("not logged in, showing LoginPage");
        }
        setLoading(false);
      })
      .catch((err) => {
        console.log(err);
        setLoading(false);
      });
  }, []);

  return (
    <>
              <Button
                title="btn"
                onPress={() => {
                  navigation.navigate("LoginScreen")
                }}
              ></Button>

export default UserProfile;

CodePudding user response:

Inside the BottomTabNavigator you can check if the user is logged in. You can get the user in the same way you're getting it in UserProfile.tsx file.


export const BottomTabNavigator = () => {
  const [user, setUser] = React.useState(null);

  React.useEffect(() => {
    // check for user
  }, []);
  
  return (
    <Tab.Navigator
      screenOptions={{ ... }}
    >
     <Tab.Screen
        name="LoginRoutes"
        component={user ? UserScreen : LoginScreen}
      />
    </Tab.Navigator>
  );
};

Alternatively, you can look into getting the user through Context Provider so that you don't have to check the storage every time you want to see if the user is logged in.

Read more about that here:

How To Manage User State with React Context

React Context

  • Related