防止用户在登录后访问登录或注册页面,React 中的 Firebase 身份验证

Preventing user to access login or signup page if logged in, Firebase auth in React

我试图阻止用户在登录后访问登录和注册页面。我试图在这里或 Youtube 上找到一些解决方案,但没有找到我要找的东西。与此同时,我试图自己实现它,并且我设法用 useEffect 钩子做到了。我不确定这是否是最佳实践,所以请检查下面的代码,如果有人知道更好的方法,那对我来说意义重大,因为我是初学者,而且我仍然有很多未知数。要清楚一切正常,只是想知道如果用户存在,使用 useEffect 导航回到主页是否是一个好习惯。

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>
  );
};

这是我设置用户 onAuthStateChange 的 UserAuthContextProvider 的一部分

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>
  );

在 Signin 组件中,我刚刚使用 useEffect 来检查是否有用户重定向回主页

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

解决方案可能是创建一个组件 ProtectedHomeRoute,做相反的事情,类似于 Signin 中的 useEffect;想了想,没必要用Effect。 例如:

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

那么在你的 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>
  );
};

尽管认为这是一个解决方案,但刷新页面会导致数据丢失(因为 user 刷新时设置为 '')。我建议您使用一些库来更改此行为,如 Redux, Redux persist...