I've been trying to set up a simple tabs navigation in my Ionic React app, linking one page to another, but I can't seem to get it right. I've implemented similar tabs on other pages using the same structure, and they work perfectly. However, for my landing page, the tabs do not work as expected.
This setup works perfectly on other pages:
ionic
const Perfil: React.FC = () => {
return (
<IonTabs>
<IonTabBar slot="bottom">
<IonTabButton tab="Tab1perfil" href="/menu/perfil/Tab1perfil">
<IonIcon icon={personOutline} />
<IonLabel>Perfil</IonLabel>
</IonTabButton>
<IonTabButton tab="Tab2perfil" href="/menu/perfil/Tab2perfil">
<IonIcon icon={settingsOutline} />
<IonLabel>Configurações</IonLabel>
</IonTabButton>
</IonTabBar>
<IonRouterOutlet>
<Route path="/menu/perfil/Tab1perfil" component={Tab1perfil} />
<Route path="/menu/perfil/Tab2perfil" component={Tab2perfil} />
<Route exact path="/menu/perfil">
<Redirect to="/menu/perfil/Tab1perfil" />
</Route>
</IonRouterOutlet>
</IonTabs>
);
};
This is the code for my landing page, which does not work as expected:
ionic
const Inicial: React.FC = () => {
return (
<IonTabs>
<IonTabBar color={"dark"} slot="bottom">
<IonTabButton tab="Ofertas" href="/menu/Inicial/Ofertas">
<IonIcon color="tbpink" icon={pricetagOutline} />
<IonLabel color="tbpink">Ofertas</IonLabel>
</IonTabButton>
<IonTabButton tab="Trending" href="/menu/Inicial/Trending">
<IonIcon color="tbpink" icon={flameOutline} />
<IonLabel color="tbpink">Populares</IonLabel>
</IonTabButton>
</IonTabBar>
<IonRouterOutlet>
<Route path="/menu/Inicial/Trending" component={Trending} exact />
<Route path="/menu/Inicial/Ofertas" component={Ofertas} exact />
<Route exact path="/menu/Inicial">
<Redirect to="/menu/Inicial/Ofertas" />
</Route>
</IonRouterOutlet>
</IonTabs>
);
};
export default Inicial;
Here is my App.tsx
for context:
ionic
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path="/">
<Login />
</Route>
<Route path="/register" component={Register} exact />
<Route path="/login">
<Login />
</Route>
<Route path="/menu" component={Menu} />
<Route path="/Trending" component={Trending} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
export default App;
Login function for context:
ionic
const [present, dismiss] = useIonLoading();
const router = useIonRouter();
const DoLogin = async (event: any) => {
event.preventDefault();
await present("Fazendo Login...");
setTimeout(async () => {
dismiss();
router.push("/menu", "root");
}, 200);
console.log("DoLogin");
};
My menu component:
ionic
const Menu: React.FC = () => {
const paths = [
{ name: "Inicial", url: "/menu/inicial", icon: homeOutline },
{ name: "Perfil", url: "/menu/perfil", icon: personOutline },
{ name: "Carrinho", url: "/menu/carrinho", icon: cartOutline },
{ name: "Configurações", url: "/menu/settings", icon: settingsOutline },
];
return (
<IonPage color={"dark"}>
<IonContent color={"dark"}></IonContent>
<IonMenu color="tbpurple" contentId="main">
<IonHeader color="tbpink">
<IonToolbar color={"dark"}>
<IonTitle color="tbpink">Menu</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent color="dark" className="ion-padding">
{paths.map((item, index) => (
<IonMenuToggle key={index}>
<IonItem
color={"dark"}
routerLink={item.url}
routerDirection="none"
>
<IonIcon slot="start" color="tbpink" icon={item.icon} />
<IonText color={"tbpink"}>{item.name}</IonText>
</IonItem>
</IonMenuToggle>
))}
</IonContent>
</IonMenu>
<IonRouterOutlet id="main">
<Route exact path="/menu/Inicial" component={Inicial} />
<Route path="/menu/settings" component={Settings} />
<Route path="/menu/perfil" component={Perfil} />
<Route exact path="/menu">
<Redirect to="/menu/Inicial" />
</Route>
</IonRouterOutlet>
</IonPage>
);
};
export default Menu;
Please help, I'm going insane and I can't figure this out. Sorry for the spelling mistakes, English is not my first language :)
The issue is in the Menu
component, the route rendering the Inicial
component can only exactly match "/menu/inicial"
, which will obviously exclude all sub-routes, e.g. "/menu/incial/trending"
and "/menu/incial/Ofertas"
cannot be matched and rendered.
<IonRouterOutlet id="main">
<Route
exact // <-- problem!
path="/menu/Inicial" // <-- only exactly this path can match!
component={Inicial}
/>
<Route path="/menu/settings" component={Settings} />
<Route path="/menu/perfil" component={Perfil} />
<Route exact path="/menu">
<Redirect to="/menu/Inicial" />
</Route>
</IonRouterOutlet>
Remove the exact
prop from the Inicial
route so any routes with "/menu/inicial"
as a path prefix can also be matched and rendered.
<IonRouterOutlet id="main">
<Route
path="/menu/Inicial" // <-- "/menu/inicial/*"
component={Inicial}
/>
<Route path="/menu/settings" component={Settings} />
<Route path="/menu/perfil" component={Perfil} />
<Redirect exact from="/menu" to="/menu/Inicial" />
</IonRouterOutlet>