When building real-world mobile applications, you'll inevitably encounter scenarios where users need to log in or register. This concept is known as an "authentication flow." The core challenge for navigation here is to present different parts of your app based on the user's authentication status. Are they logged in? Show them their dashboard. Are they not? Redirect them to a login screen. "Conditional navigation stacks" refer to the robust pattern of dynamically switching between entire sets of navigation screens (or "stacks") based on an application's state, most commonly the user's authentication status. This isn't just about security; it's fundamental to providing a seamless and intuitive user experience right from the moment they open your app.
Practically, this means your app's root component will have two main, distinct navigation structures: an AuthNavigator (containing screens like Login, Signup, Forgot Password) and an AppNavigator (containing the main application screens such as Home, Profile, Settings, etc.). The "conditional" aspect comes into play because you only render one of these top-level navigators at any given time. Your application maintains a global state, typically a userToken or isAuthenticated flag, which dictates which navigator is displayed. This state might be managed using React Context, Redux, or simply useState in a high-level component, often persisting the token in local storage like AsyncStorage.
The implementation typically involves a root component (e.g., App.js or Root.js) that wraps NavigationContainer from @react-navigation/native. Inside, you place a simple conditional check: if (userToken) { return <AppNavigator />; } else { return <AuthNavigator />; }. When a user successfully logs in, you update the userToken state, which triggers a re-render of your root component, causing the AuthNavigator to unmount and the AppNavigator to mount. Conversely, logging out clears the userToken, reversing the switch. You might also incorporate a splash screen or loading indicator while the app initially checks for an existing userToken upon startup, preventing a flicker or showing the login screen unnecessarily to an already authenticated user.
Key Takeaways
- Structure your app with separate
AuthNavigatorandAppNavigatorstacks. - Use a global state (e.g.,
userToken) to track authentication status. - Conditionally render either
AuthNavigatororAppNavigatorbased on this state. - Logging in/out updates the state, dynamically switching navigation stacks.
- Consider a loading state during initial token verification for better UX.
Code Example
How this code works
This AppRoot component serves as the intelligent gateway for the app's navigation, dynamically deciding which set of screens to display based on a user's authentication status. Its primary job is to ensure that users are directed either to authentication flows (like login or registration) or into the main application content, depending on whether they've provided a valid userToken.
The component uses React's useState hook to manage the userToken, which represents a logged-in user. It starts with null, meaning no user is logged in initially. The entire navigation structure is contained within NavigationContainer. The key decision point is the conditional rendering logic: if userToken has a value, it renders the AppNavigator (for main screens like Home, Profile, Settings); otherwise, if userToken is null, it renders the AuthNavigator (for Login, Register screens). A crucial detail for beginners is that useState(null) means userToken is null by default, so the AuthNavigator is always the first thing a user sees when the app launches, naturally guiding them towards logging in or registering.