In Ionic with React, isHistory.push changes the urs but does not render page

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;


Comments

Popular posts from this blog

Spring Elasticsearch Operations

Network Error and Timeout on Authorize.net JS

Object oriented programming concepts (OOPs)