Search code examples
reactjsauthenticationreact-hooksreact-reduxmern

React useEffect causing "Maximum update depth exceeded" error when updating navbar for authenticated users


I'm currently working on a React application and trying to implement an authenticated user experience where the navigation bar should show a profile icon instead of the login and signup buttons. However, I've run into an issue involving the useEffect hook and useState combination, resulting in a "Maximum update depth exceeded" error.

Here's my code:

import React, { useState, useEffect } from 'react';

const App = () => {
const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
const checkAuthenticationStatus = () => {
const user = localStorage.getItem("user");
const userIsLoggedIn = user !== null;
setIsAuthenticated(userIsLoggedIn);
    };

checkAuthenticationStatus();
Empty dependency array to run the effect only once

return (
    <div>
*/}
    </div>
  );
};

I'm attempting to fetch the user's authentication status from localStorage and use it to control the visibility of elements in the navigation bar. When the user is authenticated, I want to display a profile icon; otherwise, show the login and signup buttons.

I've tried various solutions, such as moving the function outside of the useEffect, using an empty dependency array, and referring to the state directly in the useEffect. Unfortunately, none of these approaches have resolved the issue.


Solution

  • Several different parts in your code are incomplete.

    1. The closing parenthesis of useEffect is missing.
    2. Dependencies are optional for useEffect but lack thereof will end up running this effect on every render. It's up to you to decide if this is a desired behavior. I chose to pass an empty array as a dependency which runs the effect only on the first render.
    3. checkAuthenticationStatus is defined inside the useEffect which is not wrong. However if you intend to call this function only inside the effect you can omit the declaration and use its content directly.
    4. Also checkAuthenticationStatus was missing a closing bracket.

    Take a look at my code below and let me know if you have any questions via a comment.


    import React, { useState, useEffect } from 'react';
        
        
    const App = () => {
        const [isAuthenticated, setIsAuthenticated] = useState(false);
        
        useEffect(() => {
            checkAuthenticationStatus();
        }, []);
            
        const checkAuthenticationStatus = () => {
            const user = localStorage.getItem("user");
            const userIsLoggedIn = user !== null;
            setIsAuthenticated(userIsLoggedIn);
        }
        
        
        return (
            <div>
                <div>{isAuthenticated ? 'Please login' : 'Welcome user'}</div>
            </div>
        );
    };