Home > Back-end >  Preventing user to access login or signup page if logged in, Firebase auth in React
Preventing user to access login or signup page if logged in, Firebase auth in React

Time:06-02

I was trying to prevent user from accessing login and signup page once he is logged in. I was trying to find some solution here or Youtube but didn't manage to find what I was looking for. In meantime I was trying to achieve that on my own and I managed to do it with useEffect hook. I'm not sure if it's best practice so check my code below and If someone knows a better way it would mean a lot to me since I am a beginner and I still have a lot of unknowns. To be clear everything works good, just want to know if it's good practice to navigate with useEffect back to home page if user exists.

App.js

const App = () => {
  return (
    <Router>
      <UserAuthContextProvider>
        <Routes>
          <Route
            path="/home"
            element={
              <ProtectedHomeRoute>
                <Home />
              </ProtectedHomeRoute>
            }
          />
          <Route path="/" element={<Signin />} />
          <Route path="/signup" element={<Signup />} />
        </Routes>
      </UserAuthContextProvider>
    </Router>
  );
};

This is part of UserAuthContextProvider where I'm setting user onAuthStateChange

const [user, setUser] = useState("");
const [loading, setLoading] = useState(true);
useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
      setLoading(false);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  return (
    <userAuthContext.Provider
      value={{
        user,
        signUp,
        signIn,
        facebookSignIn,
        logout,
      }}
    >
      {!loading && children}
    </userAuthContext.Provider>
  );

And inside Signin component I just used useEffect to check is there is user to redirect back to home

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

CodePudding user response:

The solution could be creating a component as ProtectedHomeRoute, doing the opposite thing, similar to your useEffect inside Signin; althought, no need to useEffect. For example:

const PublicRoute = ({children}) => {
   const {user} = useUserAuth()
   return user?<Navigate to='/home'>:children
}

So then in your App.js:


const App = () => {
  return (
    <Router>
      <UserAuthContextProvider>
        <Routes>
          <Route
            path="/home"
            element={
              <ProtectedHomeRoute>
                <Home />
              </ProtectedHomeRoute>
            }
          />
          <Route path="/" element={<PublicRoute>
            <Signin />
          </PublicRoute>} />
          <Route path="/signup" element={<PublicRoute>
             <Signup />
          </PublicRoute>} />
        </Routes>
      </UserAuthContextProvider>
    </Router>
  );
};

Even thought this can be a solution, refreshing page will lead to a data loose (since user is set to '' when refreshing). I recommend you using some libraries to change this behaviour, as Redux, Redux persist...

  • Related