React中App.js内实现登录成功后重定向至/dashboard的方法
解决登录后重定向到
/dashboard的问题 你的核心问题在于:redirect 是React Router专为**路由加载器(loader)或动作函数(action)**设计的API,不能在普通事件回调里直接调用;而<Navigate>组件必须被React渲染到DOM中才会触发跳转,直接在函数里写是无效的。下面给你几种可行的解决方法:
方法1:把登录逻辑移到Login组件内部(推荐)
既然Login组件在Router上下文内部,直接在Login里使用useNavigate是最直接的方式,不用把状态和逻辑都放在App里:
修改Login组件:
import { useState, useNavigate } from 'react'; import axios from 'axios'; function Login() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const navigate = useNavigate(); const handleEmailChange = (e) => { setEmail(e.target.value); }; const handlePasswordChange = (e) => { setPassword(e.target.value); }; const handleLogin = async (e) => { e.preventDefault(); try { const resp = await axios.post('http://localhost:8000/api/login', { email, password }); if (resp.status === 200) { const { token, refreshToken } = resp.data; localStorage.setItem('token', token); localStorage.setItem('refreshToken', refreshToken); // 直接跳转 navigate('/dashboard'); } } catch (error) { console.error(error); } }; return ( <form onSubmit={handleLogin}> {/* 你的输入框和按钮 */} <input type="email" value={email} onChange={handleEmailChange} /> <input type="password" value={password} onChange={handlePasswordChange} /> <button type="submit">登录</button> </form> ); } export default Login;
修改App组件:
去掉多余的状态和回调,简化路由配置:
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import Login from './Login'; import Signup from './Signup'; function App() { const router = createBrowserRouter([ { path: '/', element: <Signup /> }, { path: '/login', element: <Login /> }, { path: '/dashboard', element: <div>Dashboard</div> } ]); return <RouterProvider router={router} />; } export default App;
方法2:通过Router实例的navigate方法跳转
如果你坚持要在App里处理登录逻辑,可以通过createBrowserRouter返回的router实例调用navigate方法:
修改App组件:
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import Login from './Login'; import Signup from './Signup'; import { useState } from 'react'; import axios from 'axios'; function App() { const [isAuthenticated, setIsAuthenticated] = useState(false); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); // 创建router实例并保存引用 const router = createBrowserRouter([ { path: '/', element: <Signup /> }, { path: '/login', element: <Login handlePasswordChange={(e) => setPassword(e.target.value)} handleEmailChange={(e) => setEmail(e.target.value)} handleSubmit={handleLogin} /> }, { path: '/dashboard', element: <div>Dashboard</div> } ]); const handleLogin = async (e) => { e.preventDefault(); try { const resp = await axios.post('http://localhost:8000/api/login', { email, password }); if (resp.status === 200) { const { token, refreshToken } = resp.data; localStorage.setItem('token', token); localStorage.setItem('refreshToken', refreshToken); setIsAuthenticated(true); // 使用router实例的navigate方法跳转 router.navigate('/dashboard'); } } catch (error) { console.error(error); } }; return <RouterProvider router={router} />; } export default App;
方法3:通过状态控制渲染Navigate组件
利用React状态,当登录成功后渲染<Navigate>组件触发跳转:
修改App组件:
import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom'; import Login from './Login'; import Signup from './Signup'; import { useState } from 'react'; import axios from 'axios'; function App() { const [isAuthenticated, setIsAuthenticated] = useState(false); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [shouldRedirect, setShouldRedirect] = useState(false); const handleLogin = async (e) => { e.preventDefault(); try { const resp = await axios.post('http://localhost:8000/api/login', { email, password }); if (resp.status === 200) { const { token, refreshToken } = resp.data; localStorage.setItem('token', token); localStorage.setItem('refreshToken', refreshToken); setIsAuthenticated(true); // 设置重定向状态 setShouldRedirect(true); } } catch (error) { console.error(error); } }; // 如果需要重定向,渲染Navigate组件 if (shouldRedirect) { return <Navigate to="/dashboard" replace />; } const router = createBrowserRouter([ { path: '/', element: <Signup /> }, { path: '/login', element: <Login handlePasswordChange={(e) => setPassword(e.target.value)} handleEmailChange={(e) => setEmail(e.target.value)} handleSubmit={handleLogin} /> }, { path: '/dashboard', element: <div>Dashboard</div> } ]); return <RouterProvider router={router} />; } export default App;
注意:方法3需要注意组件重新渲染的时机,确保shouldRedirect状态更新后能触发Navigate的渲染。
内容的提问来源于stack exchange,提问作者Ashutosh Dubey
相关产品推荐
相关产品推荐

