React-Navigation | Ionian documentation (2023)

This guide describes how routing works in an app built with Ionic and React.

IonReactRouteruses the popularRouters respondLibrary under the hood. With Ionic and React Router you can create multi-page apps with rich page transitions.

Everything you know about routing with React Router is carried over to Ionic React. Let's take a look at the basics of an Ionic React app and how routing works with it.

Here is an exampleAppComponent that defines a single route to the /dashboard URL. When you go to /dashboard, the route is renderedDashboardSeiteComponents.

App.tsx

art App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route Away="/Dashboard" Components={DashboardSeite} />
<Redirect I agree out="/" to="/Dashboard" />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);

Right after theRoute, we define our standardRedirect, which when a user visits the app's root URL ("/"), redirects them to the "/dashboard" URL.

The forwarding has that tooI agreeprop set, which means the url must match theoutsupport (or theAwaysupport ifI agreewas used on oneRoute) exactly for this route being a match. Without it, this redirect would be rendered for every route since every route starts with "/".

You can also programmatically redirect from a route's rendering method based on a condition, e.g. B. Check if a user is authenticated or not:

<Route
I agree
Away="/Dashboard"
make={(props) => {
returnisAuthenticated? <DashboardSeite {...props} /> : <login page />;
}}
/>

IonReactRouter

ThatIonReactRouterComponent encloses the traditionalBrowserRouterReact Router component and sets up the app for routing. Therefore useIonReactRouterinstead ofBrowserRouter. You can pass any props toIonReactRouterand they are passed on to the underlying assetBrowserRouter.

On the dashboard page we define more routes related to this specific section of the app:

DashboardPage.tsx

art DashboardSeite: React.FC = () => {
return (
<IonPage>
<IonRouterOutlet>
<Route I agree Away="/Dashboard" Components={User List page} />
<Route Away="/dashboard/users/:id" Components={user details page} />
</IonRouterOutlet>
</IonPage>
);
};

Here are a few more routes defined that point to pages within the dashboard portion of the app. Note that we must define the entire route in the path and we cannot omit "/dashboard" even though we got to this page from that URL. React Router requires full paths and relative paths are not supported.

However, we can use theto suitobjectsURLproperty to provide the URL matched to render a component, which is useful when working with nested routes:

art DashboardSeite: React.FC<RouteComponentProps> = ({to suit}) => {
return (
<IonPage>
<IonRouterOutlet>
<Route I agree Away={to suit.URL} Components={User List page} />
<Route Away={`${to suit.URL}/users/:id`} Components={user details page} />
</IonRouterOutlet>
</IonPage>
);
};

Here,match.urlcontains the value of "/dashboard" because that was the URL used to renderDashboardSeite.

These routes are grouped into oneIonRouterOutlet, let's discuss that next.

IonRouterOutlet

ThatIonRouterOutletcomponent provides a container for routes that render ionic "pages". When a page is in aIonRouterOutlet, the container controls the animation of transitions between pages, as well as the creation and deletion of a page, which helps maintain state between views when switching back and forth between them.

ThatDashboardSeiteabove shows a user list page and a details page. When navigating between the two pages, theIonRouterOutletprovides the appropriate platform page transition and keeps the state of the previous page intact so that when a user navigates back to the list page, they see it in the same state that they left it.

AIonRouterOutletshould only containRoutes orRedirects. Every other component should either be rendered as a result of aRouteor outside ofIonRouterOutlet.

A common use case for routing is to provide a "fallback" route that is rendered if the navigated location does not match any of the defined routes.

We can define a fallback route by placing aRoutecomponent without aAway-Property as the last within a defined routeIonRouterOutlet.

DashboardPage.tsx

art DashboardSeite: React.FC<RouteComponentProps> = ({to suit}) => {
return (
<IonRouterOutlet>
<Route I agree Away={to suit.URL} Components={User List page} />
<Route Away={`${to suit.URL}/users/:id`} Components={user details page} />
<Route make={() => <Redirect to={to suit.URL} />} />
</IonRouterOutlet>
);
};

Here we see that in case a location doesn't match the first twoRouteis theIonRouterOutletredirects the Ionic React app to thematch.urlAway.

You can alternatively provide a component to render instead of providing a redirect.

art DashboardSeite: React.FC<RouteComponentProps> = ({to suit}) => {
return (
<IonRouterOutlet>
<Route I agree Away={to suit.URL} Components={User List page} />
<Route Away={`${to suit.URL}/users/:id`} Components={user details page} />
<Route Components={Page not found} />
</IonRouterOutlet>
);
};

IonPage

ThatIonPage-Component wraps each view in an Ionic React app and allows page transitions and stack navigation to work properly. Each view navigated to using the router must contain oneIonPageComponents.

import { ionic content, The IonHeader, IonPage, IonTitel, IonToolbar } out '@ionic/react';
import React out 'react';

art Heim: React.FC = () => {
return (
<IonPage>
<The IonHeader>
<IonToolbar>
<IonTitel>Heim</IonTitel>
</IonToolbar>
</The IonHeader>
<ionic content class name="ionic padding">Hallo Welt</ionic content>
</IonPage>
);
};
Export Originally Heim;

There are several options available when routing to different views in an Ionic React app. Here theUser List pageUsedIon'srouterLinkprop to specify the route to go to when the item is tapped/clicked:

UsersListPage.tsx

art User List page: React.FC = () => {
return (
<IonPage>
<The IonHeader>
<IonToolbar>
<IonTitel>user</IonTitel>
</IonToolbar>
</The IonHeader>
<ionic content>
<Ion list>
<Ion routerLink="/Dashboard/Users/1">
<IonLabel>user 1</IonLabel>
</Ion>
<Ion routerLink="/dashboard/users/2">
<IonLabel>user 2</IonLabel>
</Ion>
</Ion list>
</ionic content>
</IonPage>
);
};

Other components that have therouterLinksupport areIonButton,IonCard,IonRouterLink,IonFabButton, andIonItemOption.

Each of these components also has onerouterDirectionprop to explicitly set the type of page transition to use ("back", "forward", or "none").

Outside of these components that have therouterLinkprop you can also use React RoutershortcutComponent for navigating between views:

<shortcut to="/Dashboard/Users/1">user 1</shortcut>

We recommend using one of the above routing methods whenever possible. The advantage of these approaches is that both use an anchor (<a>) tag suitable for general app accessibility.

A programmatic option for navigation is to usestoryprop that React Router provides to the components it renders via routes.

<IonButton
onClick={(e) => {
e.prevent default();
story.to press('/dashboard/users/1');
}}
>
walktouser 1
</IonButton>

a notice

storyis a prop.

navigate withhistory.go

React Router uses thestorypackage that has onehistory.goMethod that allows developers to move forward or backward in the application history. Let's look at an example.

Suppose you have the following application history:

/ SiteA-->/SeiteB-->/SeiteC

if you would callrouter.go(-2)an/SeiteC, you would be brought back/ SiteA. Then when you calledrouter.go(2), you would be brought/SeiteC.

Usehistory.go()in Ionic React is not currently supported. Interested in seeing support for this being added to Ionic React?Let us know on GitHub!

URL-Parameter

The second route defined on the dashboard page has a URL parameter defined (the ":id" part in the path). URL parameters are dynamic parts of theAway, and when the user navigates to a URL like "/dashboard/users/1", the "1" is stored in a parameter called "id" that can be accessed in the component that renders the route. Let's see how this is done.

UserDetailPage.tsx

interface UserDetailPageProps
expanded RouteComponentProps<{
I would: line;
}> {}

art user details page: React.FC<UserDetailPageProps> = ({to suit}) => {
return (
<IonPage>
<The IonHeader>
<IonToolbar>
<IonTitel>user Detail</IonTitel>
</IonToolbar>
</The IonHeader>
<ionic content>user {to suit.Parameter.I would}</ionic content>
</IonPage>
);
};

Thatto suitprop contains information about the matched route, including the URL parameters. We get theI wouldparam here and display it on the screen.

Notice how we use a TypeScript interface to strongly type the Props object. The interface gives us type safety and code completion within the component.

Lineares Routing

If you've built a web app that uses routing, you've probably used linear routing before. Linear routing means you can move forward or backward through the application history by moving and opening pages.

The following is an example of linear routing in a mobile app:

The application history in this example has the following path:

Accessibility-->Voice-over-->Network

If we press the back button, we follow the same routing path, except in the opposite direction. Linear routing is useful in that it allows for simple and predictable routing behavior.

The disadvantage of linear routing is that it doesn't allow for complex user experiences like tabbed views. This is where nonlinear routing comes into play.

Nonlinear routing

Nonlinear routing is a concept that might be new to many web developers learning to build mobile apps with Ionic.

Nonlinear routing means that the view the user should return to is not necessarily the previous view that was displayed on the screen.

The following is an example of nonlinear routing:

In the example above, we start with thatOriginalTab. Tapping a card brings us toTeddy Lassoview within theOriginalTab.

From here we switch to theSeekTab. Then we tap theOriginaltab again and are brought back toTeddy LassoOutlook. At this point we started using nonlinear routing.

Why is this nonlinear routing? The previous view we were on was thisSeekOutlook. However, press the back button on theTeddy LassoView should bring us back to basicsOriginalOutlook. This is because each tab in a mobile app is treated as its own stack. ThatWorking with tabssection goes into more detail.

Simply invoked when tapping the back buttonHistory.go(-1)of theTeddy Lassoview, we would be brought back to thatSeekview that is not correct.

Nonlinear routing enables demanding user flows that linear routing cannot handle. Certain linear routing APIs such ashistory.go()cannot be used in this non-linear environment. It means thathistory.go()should not be used when using tabs or nested exits.

Which of them should I take?

We recommend keeping your application as simple as possible until you need to add nonlinear routing. Nonlinear routing is very powerful, but it also significantly increases the complexity of mobile applications.

The two most common uses of nonlinear routing are tabbed and nestedIonRouterOutlets. We recommend using nonlinear routing only if your application satisfies the tabbed or nested router exit use cases.

For more information about tabs, seeWorking with tabs.

For more information on nested router exits, seeNested routes.

A common point of confusion when setting up routing is deciding between shared URLs or nested routes. This part of the guide explains both and will help you decide which one to use.

Shared URLs are a route configuration where routes share parts of the URL. The following is an example of a shared URL configuration:

art App: React.FC = () => {
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route Away="/Dashboard" I agree={Is correct}>
<Dashboard main page />
</Route>
<Route Away="/Dashboard/Statistics" I agree={Is correct}>
<Dashboard stats page />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
}

The above routes are considered "shared" because they reuse thedashboardpiece of the url.

Nested routes

Nested routes are a route configuration where routes are listed as children of other routes. The following is an example of a nested route configuration:

art App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route Away="/dashboard/:id">
<DashboardRouterOutlet />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
)

art DashboardRouterOutlet: React.FC = () => (
<IonRouterOutlet>
<Route Away="/Dashboard" I agree={Is correct}>
<Dashboard main page />
</Route>
<Route Away="/Dashboard/Statistics" I agree={Is correct}>
<Dashboard stats page />
</Route>
</IonRouterOutlet>
)

The routes above are nested because they are in theKinderArray of parent route. Note that the parent route is theDashboardRouterOutletComponent. If you nest routes, you must render another instance ofIonRouterOutlet.

Which of them should I take?

Shared URLs are great when you want to go from Page A to Page B while maintaining the relationship between the two pages in the URL. In our previous example, a button is on the/Dashboardpage could switch to the/Dashboard/StatisticsSide. The relationship between the two pages is preserved because of a) the page transition and b) the URL.

Nested routes should be used when you want to render content in Outlet A while also wanting to render sub-content in a nested Outlet B. The most common use case you will come across is tabs. If you load a Tabs Ionic starter application you will seeIonTabBarandIonTabsComponents rendered in the firstIonRouterOutlet. ThatIonTabscomponent renders anotherIonRouterOutletwhich is responsible for rendering the content of each tab.

There are very few use cases where nested routes make sense in mobile applications. If in doubt, use the shared URL route configuration. We strongly caution against using nested routing in contexts other than tabs, as this can quickly become confusing for navigating your app.

Working with tabs

When working with tabs, Ionic needs to know which view belongs to which tab. ThatIonTabsComponent comes in handy here, but let's see what the routing setup for it looks like:

<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route Away="/Tabs" make={() => <tabs />} />
<Route I agree Away="/">
<Redirect to="/Tabs" />
</Route>
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</IonApp>

Here ourtabspath loads atabsComponent. We expose each tab as a route object within this component. In this example we name the pathtabs, but this can be customized.

Let's start by looking at ourstabsComponents:

import { Redirect, Route } out 'react-router-dom';
import {
ionic content,
IonIcon,
IonLabel,
IonRouterOutlet,
IonTabBar,
IonTabButton,
IonTabs
} out '@ionic/react';
import { IonReactRouter } out '@ionic/react-router';
import {Ellipse,square,triangle} out 'ionicons';
import Tab1 out './pages/Tab1';
import Tab2 out './pages/Tab2';
import tab3 out './pages/Tab3';

art tabs: React.FC = () => (
<ionic content>
<IonTabs>
<IonRouterOutlet>
<Redirect I agree Away="/Tabs" to="/Tabs/Tab1" />
<Route I agree Away="/Tabs/Tab1">
<Tab1 />
</Route>
<Route I agree Away="/tabs/tab2">
<Tab2 />
</Route>
<Route Away="/tabs/tab3">
<tab3 />
</Route>
<Route I agree Away="/Tabs">
<Redirect to="/Tabs/Tab1" />
</Route>
</IonRouterOutlet>
<IonTabBar Slot="bottom">
<IonTabButton Tab="Table 1" href="/Tabs/Tab1">
<IonIcon Symbol={triangle} />
<IonLabel>Tab 1</IonLabel>
</IonTabButton>
<IonTabButton Tab="tab2" href="/tabs/tab2">
<IonIcon Symbol={Ellipse} />
<IonLabel>Tab 2</IonLabel>
</IonTabButton>
<IonTabButton Tab="tab3" href="/tabs/tab3">
<IonIcon Symbol={square} />
<IonLabel>Tab 3</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</ionic content>
);

Export Originally tabs;

If you've worked with the Ionic Framework before, this should look familiar. We create oneIonTabscomponent and offer aIonTabBar. ThatIonTabBaroffersIonTabButtoncomponents, each with aTabproperty associated with the corresponding tab in the router configuration. We also offer oneIonRouterOutletgiveIonTabsan outlet to render the different tab views.

How tabs work in Ionic

Each tab in Ionic is treated as an individual navigation stack. This means if you have three tabs in your application, each tab will have its own navigation stack. Within each stack, you can navigate forward (move a view) and backward (open a view).

This behavior is important to note because it differs from most tab implementations found in other web-based UI libraries. Other libraries typically manage tabs as a single history stack.

Because Ionic focuses on helping developers create mobile apps, the tabs in Ionic are designed to match the native mobile tabs as closely as possible. As a result, you may experience certain behaviors in Ionic's tabs that differ from the implementations of tabs you've seen in other UI libraries. Read on to learn about some of these differences.

Sub routes within tabs

If you add additional routes to tabs, you should write them as sibling routes with the parent tab as the path prefix. The following example defines the/tabs/tab1/viewRoute as siblings of/Tabs/Tab1Route. Since this new track has thoseTable 1prefix, it will be rendered withintabscomponent and tab 1 is still selected inIonTabBar.

<IonTabs>
<IonRouterOutlet>
<Redirect I agree Away="/Tabs" to="/Tabs/Tab1" />
<Route I agree Away="/Tabs/Tab1">
<Tab1 />
</Route>
<Route I agree Away="/tabs/tab1/view">
<Tab1View />
</Route>
<Route I agree Away="/tabs/tab2">
<Tab2 />
</Route>
<Route Away="/tabs/tab3">
<tab3 />
</Route>
<Route I agree Away="/Tabs">
<Redirect to="/Tabs/Tab1" />
</Route>
</IonRouterOutlet>
<IonTabBar Slot="bottom">
<IonTabButton Tab="Table 1" href="/Tabs/Tab1">
<IonIcon Symbol={triangle} />
<IonLabel>Tab 1</IonLabel>
</IonTabButton>
<IonTabButton Tab="tab2" href="/tabs/tab2">
<IonIcon Symbol={Ellipse} />
<IonLabel>Tab 2</IonLabel>
</IonTabButton>
<IonTabButton Tab="tab3" href="/tabs/tab3">
<IonIcon Symbol={square} />
<IonLabel>Tab 3</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>

Switch between tabs

Because each tab is its own navigation stack, it's important to note that these navigation stacks should never interact. This means that there should never be a button in Tab 1 that redirects a user to Tab 2. In other words, tabs should only be switched by the user tapping a tab button on the tab bar.

A good example of this in practice are the mobile applications iOS App Store and Google Play Store. These apps both offer tabbed interfaces, but neither ever guides the user through tabs. For example, the Games tab in the iOS App Store app never directs users to the Search tab and vice versa.

Let's take a look at a few common mistakes made with tabs.

A Settings tab referenced by multiple tabs

A common practice is to create a settings view as its own tab. This is great when developers need to present multiple nested settings menus. However, other tabs should never attempt to link to the Settings tab. As mentioned above, the Settings tab should only be activated by a user tapping the appropriate tab button.

If you find that your tabs need to point to the Settings tab, we recommend making the Settings view a modal usingion-modal. This is a practice found on the iOS App Store app. With this approach, each tab can represent the modal without breaking the mobile tab pattern where each tab is its own stack.

The following example shows how the iOS App Store app handles displaying an "Accounts" view from multiple tabs. By presenting the Account view in a modal, the app can work within mobile tab best practices to display the same view across multiple tabs.

Reuse views across tabs

Another common practice is to present the same view in multiple tabs. Developers often try to do this by containing the view in a single tab while directing other tabs to that tab. As mentioned above, this breaks the mobile tab pattern and should be avoided.

Instead, we recommend having routes in each tab that point to the same component. This is a practice done in popular apps like Spotify. For example, you can access an album or podcast from the Home, Search, and Your Library tabs. When accessing the album or podcast, users remain on this tab. The app does this by creating routes per tab and sharing a common component in the code base.

The example below shows how the Spotify app reuses the same album component to display content in multiple tabs. Note that each screenshot shows the same album but from a different tab.

Home pageSearch tab
React-Navigation | Ionian documentation (1)React-Navigation | Ionian documentation (2)

If you'd rather try the concepts and code described above for yourself, please visit ourlive exampleof the above topics on StackBlitz.

IonRouterOutlet in a tabbed view

When working in a tab view, Ionic React needs a way to tell which views belong to which tabs. We achieve this by taking advantage of the fact that the paths to aRouteare regular expressions.

Although the syntax looks a bit odd, it's pretty simple once you get the hang of it.

For example, the routes for a view with two tabs (Sessions and Presenters) can be set up like this:

<IonRouterOutlet>
<Route Away="/:tab(sessions)" Components={sessionspage} I agree={Is correct} />
<Route Away="/:tab(sessions)/:id" Components={Session Details} />
<Route Away="/:tab(speakers)" Components={speaker list} I agree={Is correct} />
</IonRouterOutlet>

If the url navigated was "/sessions" it would match the first route and add a url parameter named "tab" with the value "sessions" to the resultto suitpass objectsessionspage.

When a user navigates to a session details page (e.g. "/sessions/1"), the second route adds a URL parameter named "tab" with a value of "sessions". WhenIonRouterOutletsees that both pages are in the same Sessions tab, it provides an animated page transition to the new view. When a user navigates to a new tab (in this case "Speakers"),IonRouterOutletdo not know to provide the animation.

Switches in the IonRouter Outlet

SinceIonRouterOutletdoes the job of determining which routes to render, with aSwitchfrom React Router has no effect when used withinIonRouterOutlet. Switches still work as expected when used outdoorsIonRouterOutlet.

More information

For more information on routing in React using React Router see the documentation athttps://reacttraining.com/react-router/web.

Ionic 4 und React: Navigation-Paul Halliday

Top Articles
Latest Posts
Article information

Author: Rueben Jacobs

Last Updated: 01/27/2023

Views: 6073

Rating: 4.7 / 5 (57 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Rueben Jacobs

Birthday: 1999-03-14

Address: 951 Caterina Walk, Schambergerside, CA 67667-0896

Phone: +6881806848632

Job: Internal Education Planner

Hobby: Candle making, Cabaret, Poi, Gambling, Rock climbing, Wood carving, Computer programming

Introduction: My name is Rueben Jacobs, I am a cooperative, beautiful, kind, comfortable, glamorous, open, magnificent person who loves writing and wants to share my knowledge and understanding with you.