React中Private Route登录后无法跳转至Dashboard问题求助
问题描述
直接访问http://localhost:3001/dashboard时,页面能正确跳转到/signin;但使用正确账号登录后,路由未切换至/dashboard,仍停留在/signin。服务器连接正常,当前仅支持单用户登录,需排查问题原因。
主App代码片段(所有库已正确导入)
useEffect(() => { fetch('http://localhost:3000') .then((response) => response.json()) .then(console.log) }) const [user, setUser] = useState(false); const isUserValid = (user) => { setUser(user); } return ( <Routes> <Route path="/signin" element={<Signin userValue={isUserValid} />} /> <Route path="/register" element={<Register />} /> <Route path="/dashboard" element={<PrivateRoute userValid={user} />}> <Route element={<Dashboard />} path="/dashboard" /> </Route> </Routes> )
服务器代码(Node.js + express.json + cors)
app.post('/signin', (req, res) => { if(req.body.email === database.users[0].email && req.body.password === database.users[0].password){ res.json('success'); } else { res.status(400).json('error'); } })
Private Route模块代码
const PrivateRoute = ({children, userValid}) => { return userValid ? children : <Navigate to="/signin" />; } export default PrivateRoute;
Signin模块代码(表单可正常获取输入值并与服务器交互)
const Signin = ({userValue}) => { const [userEmail, setUserEmail] = useState(''); const [userPassword, setUserPassword] = useState(''); const onEmailChange = (event) => { setUserEmail(event.target.value); } const onPasswordChange = (event) => { setUserPassword(event.target.value); } const onSubmitSignIn = () => { fetch('http://localhost:3000/signin', { method: 'post', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ email: userEmail, password: userPassword }) }) .then(response => response.json()) .then(data => { if(data === 'success'){ userValue(true); window.location.href = "/dashboard"; } }) }
问题原因及修复方案
1. 页面刷新导致登录状态丢失
登录成功后用window.location.href = "/dashboard"会触发全页面刷新,App组件的user状态会被重置为初始值false,PrivateRoute检测到未登录,就会再次跳回/signin。
修复:改用React Router的useNavigate钩子跳转,避免页面刷新:
// 在Signin组件中导入useNavigate import { useNavigate } from 'react-router-dom'; // 组件内初始化navigate const navigate = useNavigate(); // 替换window.location.href为 navigate('/dashboard');
2. 嵌套路由路径配置错误
当前Dashboard子路由的路径写为/dashboard,会和父路由的/dashboard重复,最终路径变成/dashboard/dashboard,导致路由不匹配。
修复:将子路由路径改为相对路径"":
<Route path="/dashboard" element={<PrivateRoute userValid={user} />}> <Route element={<Dashboard />} path="" /> </Route>
或者简化路由结构,直接把Dashboard作为PrivateRoute的子元素:
<Route path="/dashboard" element={<PrivateRoute userValid={user}><Dashboard /></PrivateRoute>} />
可选优化:登录状态持久化
页面刷新后user状态会丢失,可将状态存入localStorage,在App初始化时读取:
// App组件中修改useState初始化 const [user, setUser] = useState(() => { return localStorage.getItem('isLoggedIn') === 'true'; }); // 修改isUserValid函数 const isUserValid = (isLoggedIn) => { setUser(isLoggedIn); localStorage.setItem('isLoggedIn', isLoggedIn.toString()); }
内容的提问来源于stack exchange,提问作者Norbert Dąbrowski
相关产品推荐
相关产品推荐

