How to get page transitions for every page of an Ionic 5 React App?

701 views Asked by At

I'm building an app with Ionic 5 and React that I thought would be working like a SPA.

My problem is that I don't get any page transitions. When I click on a link to a subpage, the browser loads the page as you'd expect it from a classic website.

I tried the approach they recommend in their documentation, but it didn't work.

The only time I get a page transition is when I click back on the settings page. I don't get a page transition when I click on the settings link on the profile page.

How can I get transitions for every page without classic browser loading?

Thanks in advance!

Edit 1: Added the code of my routing file Edit 2: Added 3 other files ()

App.tsx

        import {
      IonApp, IonRouterOutlet,
    } from '@ionic/react';
    import { IonReactRouter } from '@ionic/react-router';
    import React from 'react';
    import { Route } from 'react-router-dom';
    import AppTabs from './AppTabs';
    
    import {setupConfig} from '@ionic/react'
    import HomePage from './pages/HomePage';
    import ExplanationPage from './pages/ExplanationPage'
    import LoginPage from './pages/LoginPage';
    import SignupPage from './pages/SignupPage';
    import VerificationSentPage from './pages/VerificationSentPage';
    import VerificationConfirmedPage from './pages/VerificationConfirmedPage';
    import ForgotPage from './pages/ForgotPage';
    import ResetLinkSentPage from './pages/ResetLinkSentPage';
    import ResetConfirmedPage from './pages/ResetConfirmedPage';
    import NewPasswordPage from './pages/NewPasswordPage';
    import SettingsPage from './pages/SettingsPage';
    import GameLoaderPage from './pages/gameLoaderPage';
    import GameEndPage from './pages/gameEndPage';
    import GamePage from './pages/GamePage';
    import GamePageTest from './pages/GamePageTest';
    import SubcategoriesPage from './pages/SubcategoriesPage'
    import DifficultyPage from './pages/DifficultyPage';
    import ModePage from './pages/ModePage';
    import { setTheme } from './functions/setTheme';
    
    setupConfig({
        mode: 'ios'
    })
    
    setTheme()
    
    const App: React.FC = () => {
      return (
        
        <IonApp>
          <IonReactRouter>
            <IonRouterOutlet>
              
              <Route component={LoginPage} path="/login" exact />
              <Route component={SignupPage} path="/signup" exact />
              <Route component={VerificationSentPage} path="/verification-sent" exact />
              <Route component={VerificationConfirmedPage} path="/verify-account" />
              <Route component={ForgotPage} path="/forgot" exact />
              <Route component={ResetLinkSentPage} path="/reset-sent" exact />
              <Route component={NewPasswordPage} path="/reset" exact />
              <Route component={ResetConfirmedPage} path="/reset-confirmed" exact />
              <Route component={SubcategoriesPage} path="/c/:category" exact />
              <Route component={DifficultyPage} path="/c/:category/:subcategory" exact />
              <Route component={ModePage} path="/c/:category/:subcategory/:id" exact />
              <Route component={ExplanationPage} path="/explanation" exact />   
    
              <Route component={SettingsPage} path="/settings" exact />
              <Route component={GameLoaderPage} path="/gameloader" exact />
              <Route component={GamePage} path="/game" exact />
              <Route component={GameEndPage} path="/gameEnd" exact />
              <Route component={GamePageTest} path="/gamePageTest" exact />
    
              <AppTabs />
    
            </IonRouterOutlet>
          </IonReactRouter>
      </IonApp>
      );
    };
    
    export default App;

AppTabs.tsx

import {
  IonIcon,
  IonRouterOutlet,
  IonTabBar,
  IonTabButton,
  IonTabs,
} from '@ionic/react';
import {person as personIcon, 
        trophy as trophyIcon,
        gameController as playIcon
        } from 'ionicons/icons';
import React from 'react';
import HomePage from './pages/HomePage';
import ProfilePage from './pages/ProfilePage';
import LeaderboardPage from './pages/LeaderboardPage';
import GameEndPage from './pages/gameEndPage';
import { Redirect, Route } from 'react-router';
import { IonReactRouter } from '@ionic/react-router';

const AppTabs: React.FC = () => {
  return (
    <IonReactRouter>
      <IonTabs>

        <IonRouterOutlet>
          <Route path="/home" component={HomePage} exact={true} />
          <Route path="/profile" component={ProfilePage} exact={true} />
          <Route path="/leaderboard" component={LeaderboardPage} />
          <Route path="/" render={() => <Redirect to="/home" />} exact={true} />
        </IonRouterOutlet>

        <IonTabBar slot="bottom">
          <IonTabButton tab="home" href="/home">
            <IonIcon icon={playIcon} />
          </IonTabButton>
          
          <IonTabButton tab="profile" href="/profile">
            <IonIcon icon={personIcon} />
          </IonTabButton>

          <IonTabButton tab="leaderboard" href="/leaderboard">
            <IonIcon icon={trophyIcon} />
          </IonTabButton>
        </IonTabBar>

      </IonTabs>
    </IonReactRouter>
  );
};

export default AppTabs;

ProfilePage.tsx

import {
  IonButton,
  IonButtons,
  IonCol,
    IonContent,
    IonGrid,
    IonHeader,
    IonIcon,
    IonPage,
    IonRow,
    IonText,
    IonTitle,
    IonToolbar,
  } from '@ionic/react';
  import {
    settings as settingsIcon,
    flame as flameIcon,
    flash as flashIcon,
    medal as medalIcon
  } from 'ionicons/icons';
  import React from 'react';
import ShowBadges from '../functions/showBadges';
import { globalVariables } from '../functions/variables.js'

let v = globalVariables()
  
const ProfilePage: React.FC = () => {
  return (
    <IonPage>

      <IonHeader>
        <IonToolbar>
          <IonGrid>
            <IonRow>

              <IonCol size="12" >
                <IonTitle>Profil</IonTitle>
                <IonButton color="transparent" href="/settings" target="">
                  <IonIcon color="dark" slot="icon-only" icon={settingsIcon}/>
                </IonButton>
              </IonCol>

            </IonRow>
          </IonGrid>
        </IonToolbar>
      </IonHeader>

      <IonContent className="ion-padding-top" overflow-scroll="false">

        <IonGrid>
          <IonRow className="statsSection">

            <IonCol size="4" className="streak" >
              <IonButtons className="ProfileIcons" >
                  <IonIcon slot="icon-only" icon={flameIcon} />
              <div>
                <IonText className="smallCaptionIconsHeading">{v.activity_streak}
                <span className="smallCaptionIcons">Streak-Tage</span></IonText>
              </div>            
              </IonButtons>
            </IonCol>

            <IonCol size="4" className="xp" >
              <IonButtons className="ProfileIcons" >
                  <IonIcon slot="icon-only" icon={flashIcon} />
              <div>
                <IonText className="smallCaptionIconsHeading">{v.xp}
                <span className="smallCaptionIcons">Erzielte XP</span></IonText>
              </div>   
              </IonButtons>         
            </IonCol>

            <IonCol size="4" className="medals" >
              <IonButtons className="ProfileIcons" >
                  <IonIcon slot="icon-only" icon={medalIcon} />
              <div>
                <IonText className="smallCaptionIconsHeading">{v.number_of_crowns}
                <span className="smallCaptionIcons">Medalien</span></IonText>
              </div>   
              </IonButtons>         
            </IonCol>

          </IonRow>
        </IonGrid>

        <IonText className="ion-padding sectionHeading">Abzeichen</IonText>

        <ShowBadges/>

      </IonContent>
    </IonPage>
  );
};
  
  export default ProfilePage;

SettingsPage.tsx

import {
  IonAlert,
  IonBackButton,
  IonButton,
  IonButtons,
  IonContent,
  IonHeader,
  IonInput,
  IonItem,
  IonLabel,
  IonList,
  IonPage,
  IonText,
  IonTitle,
  IonToggle,
  IonToolbar,
  useIonToast,
} from '@ionic/react';
import React, { useState } from 'react';
import { getSettings, setSettings } from '../functions/setSettings';
import { setTheme } from '../functions/setTheme';

const SettingsPage: React.FC = () => {

  const settings = getSettings()
  const [darkmode, setDarkmode] = useState(settings.darkmode);
  const [sound, setSound] = useState(settings.sound);

  const [present, dismiss] = useIonToast();

  function saveSettings() {
    setSettings(sound, darkmode)
    setTheme()
    present('Einstellungen gespeichert!', 3000)
  }

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonButtons slot="start">
            <IonBackButton defaultHref="/profile" />
          </IonButtons>
          <IonTitle>Einstellungen</IonTitle>
        </IonToolbar>
      </IonHeader>
      
      <IonContent className="ion-padding">
          <div className="toggleButtons">
          <IonText className="inputLabel">Allgemein</IonText>
            <IonItem className="settingsLabel">
              <IonLabel>Sound</IonLabel>
              <IonToggle id="sound" checked={sound} onIonChange={e => setSound(e.detail.checked)}/>
            </IonItem>

            <IonItem className="settingsLabel">
              <IonLabel>Darkmode</IonLabel>
              <IonToggle id="darkmode" checked={darkmode} onIonChange={e => setDarkmode(e.detail.checked)}/>
            </IonItem>
          </div>
        
        {/* SETTINGS FOR ACCOUNT
          <IonText className="inputLabel">Name</IonText>

          <IonItem className="inputField">
            <IonInput value="Maurice"> </IonInput>
          </IonItem>

          <IonText className="inputLabel">Benutzername</IonText>

          <IonItem className="inputField">
            <IonInput value="Maurice99"> </IonInput>
          </IonItem>

          <IonText className="inputLabel">E-Mail</IonText>

          <IonItem className="inputField">
            <IonInput value="[email protected]"> </IonInput>
          </IonItem>

          <IonText className="inputLabel">Passwort</IonText>

          <IonItem className="inputField">
            <IonInput type="password"> </IonInput>
          </IonItem>

        */}

          <IonButton expand="block" onClick={() => saveSettings()}>Speichern</IonButton>

          <div className="legalLinks">
              <a href="https://x.de/impressum">Impressum</a>
              <a href="https://x.de/datenschutzerklarung/">Datenschutzerklarung</a>
          </div>

      </IonContent>
    </IonPage>
  );
};

export default SettingsPage;
1

There are 1 answers

2
Yannick Lionel On

You should use the routerLink on the instead of href to get the page transitions