React maximum update depth exceeded | useEffect with user from firebase

Viewed 121

I'm receiving the maximum update depth exceeded on some random occasions. I am using the useEffect hook to navigate the user to the login screen when not authenticated, and navigate him into the home page when he is authenticated and tries to access the login screen. I am getting the user from firebase useAuthState.

Here is the login page code

import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from "react-router-dom";
import {
  getAuth,
  signInWithEmailAndPassword,
} from "firebase/auth";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth } from "../Firebase";


function Login (){
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [user, loading] = useAuthState(auth);
  const navigate = useNavigate();

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };
  const handlePasswordChange = (e) => {
    setPassword(e.target.value);
  };  
  const handleLogin = () => {
      const auth = getAuth();
      signInWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        localStorage.setItem('email', auth.currentUser.email);
      })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        console.log(errorCode);
        console.log(errorMessage);
      });
    };

    useEffect(() => {
      if (user) navigate("/home");
    }, [user, loading, navigate]);
    
    return (
    <div class="fill-window login-bg">
      <div class="container login-container">
        <h1 class="login-h1"> Bienvenu ! </h1>
        <h2 class="login-h2"> Connectez-vous pour entrer dans votre espace virtuel </h2>
        <div class="row login-row1">
          <div class="col">
            <label for="inputEmail4" class="form-label label-login">Mail</label>
            <input type="email" 
              class="form-control login-input" 
              id="inputEmail4" 
              value={email}
              onChange={handleEmailChange}/>
          </div>
        </div>
        <div class="row login-row2">
          <div class="col">
            <label for="userPassword" class="form-label label-login">Mot de passe</label>
            <input type="password" 
              class="form-control login-input" 
              id="userPassword" value={password} 
              onChange={handlePasswordChange}/>
          </div>
        </div>
        <div style={{textAlign: "center", paddingTop: "2rem"}}>
        <button class="btn btn-light login-button" onClick={handleLogin}>SE CONNECTER</button>
        </div>
        <div class="row login-link-row">
          <div class="login-page-links">
          <Link to="/forgotPassword" class="link-dark forgot-password">Mot de pass oublié?</Link>
          </div>
          <div class="login-page-links">
          <Link to="/signup" class="link-dark signup">Créér une compte</Link>
          </div>
        </div>
      </div>
      </div>
    );
}
export default Login;

And here is the homePage code

import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import {Link} from "react-router-dom";
import MyCarousel from './MyCarousel';
import {
    getAuth,
    signOut,
  } from "firebase/auth";
import { useAuthState } from "react-firebase-hooks/auth";

function HomePage() {
    const auth = getAuth();
    const [user, loading] = useAuthState(auth);  
    const navigate = useNavigate();
    const HandleSignout = () => {
        signOut(auth).then(() => {
            localStorage.removeItem('email');
          }).catch((error) => {
            console.log('could not sign-out due to ' + error)
          });
    }
   useEffect(() => {
     if (!user) return navigate("/login");
   }, [user, loading, navigate]);
    
    return (
        <div class='communication-main-container'>
            <div class='communication-display'>
                <MyCarousel/>
            </div>
            <button onClick={HandleSignout}>Log out</button>
            <Link to="/communication">Navigate</Link>
        </div>
    );
}
export default HomePage;
1 Answers

This is happening because from login page it's redirecting user to home page when there is a change in user, loading, navigate any of these value and from home page it's redirecting user to login page when there is a change in above mentioned value so basically it's going in infinite loop.

So change the dependency array in both the components:

login page component

useEffect(() => {
  if (user) navigate("/home");
}, [user])

home page component

useEffect(() => {
   if (!user) return navigate("/login");
}, [user]);
Related