search

Home  >  Q&A  >  body text

Navigation restrictions to prevent the browser from hanging on my console

<p>A PrivateRoute was created for the dashboard page, which is not accessible via the URL when not logged in, but refreshing the dashboard page results in a redirect to the authentication page. So I added a sessionStorage, but now when refreshing it says "throttling navigation to prevent the browser from hanging" on my console because it keeps redirecting to the page.</p> <p>//以下是代码</p> <p>//App.js</p> <pre class="brush:php;toolbar:false;">import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Dashboard from "./components/dashboard"; import Auth from "./components/auth"; import PrivateRoute from "./PrivateRoute"; function App() { return ( <Router> <Routes> <Route path="/signin" element={<Auth />} /> <Route path="/dashboard" element={<PrivateRoute> <Dashboard /></PrivateRoute>} /> </Routes> </Router> ); } export default App;</pre> <p>//PrivateRoute.js</p> <pre class="brush:php;toolbar:false;">import { Navigate } from "react-router-dom"; import { auth } from "./config/firebase"; function PrivateRoute({ children }) { const user = auth.currentUser; // 检查用户是否已经通过身份验证 if (!user) { // 用户未通过身份验证,重定向到登录页面 return <Navigate to="/signin" replace/>; } // 用户已通过身份验证,渲染受保护的路由 return children; } export default PrivateRoute;</pre> <p>//Auth.js</p> <pre class="brush:php;toolbar:false;">import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { auth, googleProvider } from "../config/firebase"; import { createUserWithEmailAndPassword, signInWithPopup, signOut, } from "firebase/auth"; function Auth () { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const navigate = useNavigate(); console.log(auth?.currentUser?.email); useEffect(()=> { const userFromStorage = JSON.parse(sessionStorage.getItem("user")); if(userFromStorage){ console.log(userFromStorage); navigate("/dashboard"); } } , [navigate]); const signIn = async () => { try { await createUserWithEmailAndPassword(auth, email, password); sessionStorage.setItem("user" , JSON.stringify(auth.currentUser)); navigate("/dashboard"); } catch (err) { console.error(err); } }; const signInWithGoogle = async () => { try { await signInWithPopup(auth, googleProvider); sessionStorage.setItem("user", JSON.stringify(auth.currentUser)); navigate("./dashboard"); }catch (err) { console.error(err); } }; const Logout = async () => { try { await signOut(auth); sessionStorage.removeItem("user"); } catch (err) { console.error(err); } }; return ( <div> <input placeholder="email" onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="password" onChange={(e) => setPassword(e.target.value)} /> <button onClick={signIn}>sign in</button> <button onClick={signInWithGoogle}>sign in with Google</button> <button onClick={Logout}>Logout</button> </div> ); }; export default Auth;</pre> <p>Don't want this error, as a beginner, if there is room for improvement, please feel free to let me know. </p>
P粉226413256P粉226413256465 days ago609

reply all(1)I'll reply

  • P粉337385922

    P粉3373859222023-08-17 07:17:06

    You should handle authentication status asynchronously.

    import { useEffect, useState } from 'react';
    import { Navigate } from 'react-router-dom';
    import { auth } from './config/firebase';
    
    function PrivateRoute({ children }) {
      const [isAuthenticated, setIsAuthenticated] = useState(false);
      const [loading, setLoading] = useState(true);
    
      useEffect(() => {
        // 观察用户身份验证变化
        const unsubscribe = auth.onAuthStateChanged((user) => {
          if (user) {
            setIsAuthenticated(true);
          } else {
            setIsAuthenticated(false);
          }
          setLoading(false);
        });
    
        // 当组件卸载时取消订阅
        return () => unsubscribe();
      }, []);
    
      if (loading) return <div>加载中...</div>; // 可选的加载指示器
    
      if (!isAuthenticated) {
        return <Navigate to="/signin" replace />;
      }
    
      return children;
    }
    
    export default PrivateRoute;

    reply
    0
  • Cancelreply