reactjsfirebaseconditional-statementspersistentrerender

How fix two pages render in ternary navigation return


I'm trying to implement a persistent login session in react with firebase, it works kind of good, but i have a problem with the initial state and the re-render of the component, the initial state of currentUser it's null then the useEffect from the useAuth component renders and check if it's a logged user, and set the currentUserto a truthy value.

useAuth component:

  useEffect(() => {
    console.log("Rerendered useAuth");

    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        console.log("We are authenticated now!");
        setCurrentUser(user);
      } else {
        console.log("The user is not logged!");
        setCurrentUser(null);
      }
    });
    // Cleanup subscription on unmount
    return () => unsubscribe();
  }, []);

Ternary return in navigation:

function MainNavigator() {
  const { currentUser } = useAuth();
  const Stack = createNativeStackNavigator();

  return (
    <Stack.Navigator
      screenOptions={{ headerShown: false }}
      initialRouteName={RoutesEnum.landing}
    >
      {currentUser ? (     // null at first, then truthy
        <>
          <Stack.Screen
            name={RoutesEnum.tabNavigator}
            component={TabNavigator}
          />
          <Stack.Screen name={RoutesEnum.stories} component={Stories} />
        </>
      ) : (
        <>
          <Stack.Screen name={RoutesEnum.landing} component={Landing} />
          <Stack.Screen name={RoutesEnum.login} component={Login} />
          <Stack.Screen name={RoutesEnum.register} component={Register} />
          <Stack.Screen name={RoutesEnum.myAccount} component={MyAccount} />
          <Stack.Screen
            name={RoutesEnum.forgotPassword}
            component={ResetPassword}
          />
        </>
      )}
    </Stack.Navigator>
  );
}

The problem:

At the first renders the landing page (for a few milliseconds) because the initial state its null, then renders the useAuth and with the useEffect logs the user, and then navigates to the home.

How can i fix this issue that renders the two screens


Solution

  • Check if your "useAuth" hook returns a loading prop, it generally should. Then youll have something like this:

    const { currentUser, loading } = useAuth();
    const Stack = createNativeStackNavigator();
    
    if (loading) return null;
    
    return (
    // ... rest of your code
    
    

    You can also do if (loading) return <LoadingPage/> if you build a component like that out