skip to Main Content

In my Ionic app, I have a login screen and a dashboard screen.

When log in succeeds in Login.tsx, a user is created, then console.log("Go to dashboard") runs, followed by history.push("/dashboard"), which should show the Dashboard. The problem is that history.push changes the url to /dashboard but the dashboard page is not shown and I only still see the login view, even though "Stay in Dashboard" is printed in the console. If I then refresh the page, the correct Dashboard view is shown.

How do I fix this? Is this because Ionic cannot use isHistory? I also tried using import { useHistory } from "react-router-dom"; in Login screen instead of getting history from props with the same result. What is the correct way to change route in Ionic-React?

App.tsx

...
const App: React.FC = () => (
  <IonApp>
    <IonReactRouter>
      <IonRouterOutlet>
        <Route exact path="/login" component={Login} />
        <Route exact path="/dashboard"><Dashboard /></Route>
        <Route exact path="/"><Redirect to="/login" /></Route>
      </IonRouterOutlet>
    </IonReactRouter>
  </IonApp>
);

Login.tsx

import React, { useEffect, useState } from 'react';
import { RouteComponentProps } from "react-router-dom";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth } from "../config/firebase";

const Login: React.FC<RouteComponentProps> = ({ history }) => {
  // const history = useHistory();
  const [ email, setEmail ] = useState<string>("");
  const [ password, setPassword ] = useState<string>("");
  const [ user, loading, error ] = useAuthState(auth);

  useEffect(() => {
    if (loading) { return; }
    if (user) {
      console.log("Go to dashboard")
      history.push("/dashboard");
    }
  }, [user, loading]);

  const handleCredentials = () => {
    // log in
  }

  return (
    <IonPage className="login-page">
      <IonContent fullscreen className="ion-padding ion-text-center">
        <IonGrid>
          <IonRow>
            <IonCol>
              <IonItem>
                <IonLabel position="floating"> Email</IonLabel>
                <IonInput
                  type="email"
                  value={email}
                  onIonChange={(e) => setEmail(e.detail.value!)}
                  placeholder="Email Address"
                ></IonInput>
              </IonItem>
            </IonCol>
          </IonRow>
          <IonRow>
            <IonCol>
            <IonItem>
              <IonLabel position="floating"> Password</IonLabel>
              <IonInput
                type="password"
                value={password}
                onIonChange={(e) => setPassword(e.detail.value!)}
                placeholder="Password"
              ></IonInput>
            </IonItem>
            </IonCol>
          </IonRow>
          <IonRow>
            <IonCol>
              <IonButton className="login__btn" expand="block" onClick={handleCredentials}>Login</IonButton>
            </IonCol>
          </IonRow>
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Login;

Dashboard.tsx

import React, { useEffect, useState } from "react";
import { RouteComponentProps } from "react-router-dom";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth } from "../config/firebase";

const Login: React.FC<RouteComponentProps> = ({ history }) => {
  const [user, loading, error] = useAuthState(auth);
  useEffect(() => {
    if (loading) { return; }
    if (!user) {
      console.log("Go to log in");
      return history.push("/login");
    }
    console.log("Stay in Dashboard");
  }, [user, loading]);
  return (
    <div className="dashboard">
      <div className="dashboard__container">
        Logged in
      </div>
    </div>
  );
}
export default Dashboard;

2

Answers


  1. Chosen as BEST ANSWER

    I just found the answer here: https://github.com/ionic-team/ionic-framework/issues/20707

    Simply surround your tags with <IonPage> and the redirect works. In my case, I added 2 them into Dashboard and now history.push works as expected.

        <IonPage>
          <IonContent fullscreen>
            <div className="dashboard">
              <div className="dashboard__container">
                Logged in as
                <div>{name}</div>
                <div>{user?.email}</div>
                <button className="dashboard__btn" onClick={logout}>
                  Logout
                </button>
              </div>
            </div>
          </IonContent>
        </IonPage>
    

  2. I have had similar issues in Ionic apps with routing before. One way I was able to resolve them is to render the routes additionally into the Switch component. I cannot confirm this is the "correct way", but is has worked for me in past projects.

    Example:

    import { Redirect, Route, Switch } from 'react-router-dom';
    
    ...
    
    const App: React.FC = () => (
      <IonApp>
        <IonReactRouter>
          <IonRouterOutlet>
            <Switch>
              <Route path="/login" component={Login} />
              <Route path="/dashboard" component={Dashboard} />
              <Redirect to="/login" />
            </Switch>
          </IonRouterOutlet>
        </IonReactRouter>
      </IonApp>
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search