Okay, can someone explain the best practice for handling authentication with an Ionic React Tabs application? I find several examples of applications that contain a login page before allowing the user to access the app, as a result, the tabs are not shown until a user is authenticated.
My specific use case requires that certain tabs are displayed to them while not authenticated, such as: Home
and Login
and then when a user is logged in they are presented with: Home
and Profile
. This functionality is similar to the AirBnb app. My issue is that if a user logs out, the Profile
content still hangs out in the IonRouterOutlet
in the DOM and thus not fully removed and without doing a window.location.reload
(which I really do not want to do), I am not sure how to rid myself of these DOM elements after logging out?
Everything I document below has been recreated using CodeSandbox, see that link here: cool-bash-z8f5j - CodeSandbox
My App.tsx
looks like the following:
Important notes from the code below
- A
user
object containing the logged in user is persisted through ReactsuseContext
that is wrapped around myApp.tsx
. - An
IonTabButton
is dynamically displayed depending on whether theuser
is undefined or has a value.
const App: React.FunctionComponent = () => {
const { user } = useAuth();
return (
<IonApp>
<IonReactRouter>
<IonPage id="main">
<IonTabs>
<IonRouterOutlet>
<Route path="/:tab(home)" component={Home} exact={true} />
<Route path="/:tab(login)" component={Login} exact={true} />
<Route path="/:tab(profile)" component={Profile} exact={true} />
<Route
path="/:tab(profile)/settings"
component={ProfileSettings}
exact={true}
/>
<Route exact path="/" render={() => <Redirect to="/home" />} />
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="home" href="/home">
<IonIcon icon={homeSharp} />
<IonLabel>Home</IonLabel>
</IonTabButton>
{user ? (
<IonTabButton tab="profile" href="/profile">
<IonIcon icon={send} />
<IonLabel>Profile</IonLabel>
</IonTabButton>
) : (
<IonTabButton tab="login" href="/login">
<IonIcon icon={person} />
<IonLabel>Login</IonLabel>
</IonTabButton>
)}
</IonTabBar>
</IonTabs>
</IonPage>
</IonReactRouter>
</IonApp>
);
};
- When a user is not logged in, they are shown a login tab, when the tab is clicked, they are routed to a login page.
- Now that the user has a value, the tab at the bottom switches from
Login
toProfile
and the user ispushed
to the/profile
route usingreact-router-dom
. - To logout, the user clicks the settings button on the
Profile
page which routes them to/profile/settings
. - On the settings page, the user clicks
Log out
and is routed back to/login
viapush('/login')
ofreact-router-dom
.
Here lies my problem, if you look in the DOM, the Profile
and ProfileSettings
page content still persists in the DOM:
So after logging out, what is the preferred way of managing the pages in the tab stack? Because Profile
and ProfileSettings
should not be in the router outlet anymore (logically speaking). This has also sometimes presented an issue where if a user logs back in, the router stack believes that ProfileSettings
is on the /profile
route instead of Profile
so when clicking the Profile
tab after logged in just keeps you on the ProfileSettings
page. Which I believe has to do with these DOM elements persisting and confusing the route stack on which Page
to actually show. I’ve been fighting with this for a while and finally trying to tackle this problem. Does anyone have any suggestions? Thanks!
To summarize recreating this problem:
Start on Home page → Click Login Tab → Click Login Button → Click Settings button → Click Logout Button → Inspect DOM