skip to Main Content

On login i’m storing user token or id in local storage and then i’m getting them from local storage and saving in state and on state behalf its selecting routes but if user is login and is in local storage but state takes time to render so by default state is null so its navigating on unauthenticated routes first then authenticated routes

 useEffect(()=>{
 const user=localStorage.getItem('user')
 setAuth(user)
},[])

return(
       <BrowserRouter>
        {isAuthenticated ? 
        <AuthenticatedRoutes /> 
            :
        <UnAuthenticatedRoutes />
        }
       </BrowserRouter>
)```
     

2

Answers


  1. Set a default value for the user to be undefined. Check if the user === undefined and show a loading screen until the user === null (unauthenticated) or contains a value (authenticated).

    Login or Signup to reply.
  2. If you’re getting the value from local storage there’s no need to delay it with a useEffect, since local storage is synchronous. You can just read the value from storage during the first render:

    const [auth, setAuth] = useState(localStorage.get('user'));
    

    That said, i don’t think this is the way you should be doing it with firebase auth. Firebase auth comes with an a built in ability to persist the login, so i would use that. The way to get notified that a user is logged in (including getting notified when a persisted session is restored) is with onAuthStateChanged.

    There will be an initial render where you don’t yet know whether they are logged in, similar to your original question. The solution to this is to have a loading state. If loading is true, you either render a temporary loading ui, or null if you don’t want anything to show.

    import { onAuthStateChanged } from 'firebase/auth';
    // ...
    
    const [auth, setAuth] = useState(null);
    const [loading, setLoading] = useState(true);
    useEffect(() => {
      const unsubscribe = onAuthStateChanged(user => {
        setAuth(user);
        setLoading(false);
      }, (error) => {
        console.error(error);
        setAuth(null);
        setLoading(false);
      });
      return unsubscribe;
    }, []);
    
    if (loading) {
     return <div>Loading...</div>
    }
    
    // else, return the same ui you were returning in your example
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search