Leonel de la Vega
Leonel de la Vega

Reputation: 1

React Navigation not redirecting to DrawerNavigator after app restart for one user type but works for another

I’m working on a React Native app with two user flows: Employer and Employee. Both flows are structured similarly:

The user completes an onboarding process. After onboarding, they are redirected to their respective DrawerNavigator (EmployerDrawerScreen or EmployeeDrawerScreen). On app restart, the user should be taken directly to their DrawerNavigator if they have already completed onboarding. The issue is that the Employer flow works perfectly—after restarting the app, the user is redirected to the EmployerDrawerScreen. However, in the Employee flow, after restarting the app, the user is sent back to the TypeSelectorScreen instead of the EmployeeDrawerScreen.

Additionally, I’m seeing the following error in the logs when trying to navigate to EmployeeOnboardScreen:

The action 'NAVIGATE' with payload {"name":"EmployeeOnboardScreen"} was not handled by any navigator. Do you have a screen named 'EmployeeOnboardScreen'? If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator. If you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually.

I’m using AsyncStorage to save the user’s state (accountType and hasOnboarded) during the onboarding process. I’ve verified that the Employee flow saves the state correctly in AsyncStorage when the onboarding is completed. In MainNavigation.js, I have logic to check the user’s state and redirect them to the appropriate screen based on accountType and hasOnboarded. Despite this, the Employee flow does not behave as expected after restarting the app.

Here’s a simplified version of my code:

return (
    <MainStack.Navigator>
      {!user && (
        <MainStack.Screen 
          name="AuthStack" 
          component={AuthStackScreen} 
          options={{ headerShown: false }} 
        />
      )}

      {user && !accountType && (
        <MainStack.Screen 
          name="TypeSelector" 
          options={{ headerShown: false }}
        >
          {props => <TypeSelectorScreen {...props} setAccountType={setAccountType} />}
        </MainStack.Screen>
      )}

      
      {user && accountType === 1 && (
        hasOnboarded ? (
          <MainStack.Screen 
            name="EmployerHome" 
            component={EmployerDrawerScreen} 
            options={{ headerShown: false }} 
          />
        ) : (
          <MainStack.Screen 
            name="EmployerOnboardScreen" 
            component={EmployerOnboardScreen} 
            options={{ headerShown: false }} 
          />
        )
      )}

      {user && accountType === 0 && (
        hasOnboarded ? (
          <MainStack.Screen 
            name="EmployeeHome" 
            component={EmployeeDrawerScreen} 
            options={{ headerShown: false }} 
          />
        ) : (
          <MainStack.Screen 
            name="EmployeeOnboardScreen" 
            component={EmployeeOnboardScreen} 
            options={{ headerShown: false }} 
          />
        )
      )}
    </MainStack.Navigator>
  );

This handles the onboarding flow for Employee:

export function EmployeeOnboardScreen() {
    return (
        <EmployeeStack.Navigator initialRouteName="InicioEmployee">
            <EmployeeStack.Screen name="InicioEmployee" component={InicioEmployeeScreen} options={{headerShown: false}}/>
            <EmployeeStack.Screen name="Employee1" component={Employee1Screen} options={{headerShown: false}}/>
            <EmployeeStack.Screen name="Employee2" component={Employee2Screen} options={{headerShown: false}}/>
            <EmployeeStack.Screen name="Camera" component={Camera} options={{headerShown: false}} />
            <EmployeeStack.Screen name="EmployeeDrawer" component={EmployeeDrawerScreen} options={{headerShown: false}} />
        </EmployeeStack.Navigator>
    );
}

This retrieves the user’s state from AsyncStorage on app startup:

useEffect(() => {
    const prepareResources = async () => {
      try {
        const savedAccountType = await AsyncStorage.getItem('accountType');
        console.log('Tipo de cuenta guardado:', savedAccountType);
        const onboarded = await AsyncStorage.getItem('hasOnboarded');
        console.log('Onboarded:', onboarded);

        if (savedAccountType !== null) {
          setAccountType(Number(savedAccountType));
        }
        setHasOnboarded(onboarded === 'true');
      } catch (e) {
        console.warn(e);
      } finally {
        setAppIsReady(true);
        await SplashScreen.hideAsync();
      }
    }

    prepareResources();
}, []);

Why does the Employee flow redirect to the TypeSelectorScreen after restarting the app, even though the state (accountType and hasOnboarded) seems to be saved correctly in AsyncStorage? Why am I getting the error The action 'NAVIGATE' with payload {"name":"EmployeeOnboardScreen"} was not handled by any navigator? Is the screen EmployeeOnboardScreen not registered correctly? Could this issue be related to how the EmployeeDrawerScreen is configured or how the navigation logic is implemented in MainNavigation.js?

React Navigation version: "^7.0.14"

React Native version: "0.74.5"

Expo: "~51.0.34"

Dependencies: @react-navigation/native, @react-navigation/stack, @react-navigation/drawer, AsyncStorage

Platform: Android

I am using AsyncStorage to save the user's account type (accountType) and onboarding status (hasOnboarded) during the app's initial setup. Specifically:

When the user completes the onboarding process, I save their accountType (e.g., 0 for Employee or 1 for Employer) and set hasOnboarded to true in AsyncStorage. On app restart, I retrieve these values from AsyncStorage to determine the user's state and decide which screen to navigate to: If the user has completed onboarding (hasOnboarded === true), they should be redirected to their respective home screen (EmployeeDrawerScreen or EmployerDrawerScreen). If the user has not completed onboarding, they should be sent to the onboarding flow (EmployeeOnboardScreen or EmployerOnboardScreen).

I expect that after restarting the app:

For the Employer flow: The user is correctly redirected to the EmployerDrawerScreen if they have already completed onboarding. For the Employee flow: The user should similarly be redirected to the EmployeeDrawerScreen if they have completed onboarding. However, while the Employer flow works as expected, the Employee flow does not behave correctly. After restarting the app, the Employee user is sent back to the TypeSelectorScreen instead of the EmployeeDrawerScreen.

Upvotes: 0

Views: 22

Answers (0)

Related Questions