使用useNavigate()钩子无法跳转页面问题求助
问题分析与解决方案
核心问题1:表单提交未阻止默认行为
表单默认提交动作会触发页面刷新,直接中断navigate跳转逻辑,导致页面重新加载/login路由。
修复方法
在handleSubmit函数开头添加e.preventDefault(),阻止表单默认提交行为:
const handleSubmit = async (e) => { e.preventDefault(); // 新增此行 const isValid = onSubmit(e); if (isValid) { const payLoad = {}; for (let key in formData) { payLoad[key] = formData[key]['value']; } try { const response = await login(payLoad); localStorage.setItem('user', JSON.stringify(response.data)); navigate('/home', { replace: true }); } catch (err) { console.log("inside login error"); setApiErrorMessage(err.response.data.error); } } }
核心问题2:路由权限判断仅初始化执行一次
createBrowserRouter在App组件初始化时创建,isUserValid()仅此时执行一次。登录后localStorage更新,但路由配置不会重新计算,导致/home路由仍使用初始化时的未登录判断结果,从而跳回/login。
修复方法:改用组件内动态权限判断
方式1:创建通用保护路由组件
// ProtectedRoute.jsx import { Navigate } from 'react-router-dom'; export default function ProtectedRoute({ children }) { const isAuthenticated = isUserValid(); return isAuthenticated ? children : <Navigate to="/login" replace />; }
修改App.js路由配置,将权限判断移到组件内部:
export default function App() { const router = createBrowserRouter([ { path: '/', element: <Navigate to="/home" replace />, errorElement: <Error /> }, { path: '/login', element: isUserValid() ? <Navigate to="/home" replace /> : <Login /> }, { path: '/register', element: isUserValid() ? <Navigate to="/home" replace /> : <Register /> }, { path: '/home', element: ( <ProtectedRoute> <Form /> </ProtectedRoute> ) } ]) return ( <RouterProvider router={router} /> ) }
方式2:监听storage事件触发组件重渲染
如果App组件未因localStorage变化自动重渲染,可添加事件监听更新状态:
export default function App() { const [authState, setAuthState] = useState(isUserValid()); useEffect(() => { const handleStorageChange = () => setAuthState(isUserValid()); window.addEventListener('storage', handleStorageChange); return () => window.removeEventListener('storage', handleStorageChange); }, []); const router = createBrowserRouter([ { path: '/', element: authState ? <Navigate to="/home" replace /> : <Navigate to="/login" replace />, errorElement: <Error /> }, { path: '/login', element: !authState ? <Login /> : <Navigate to="/home" replace /> }, { path: '/register', element: !authState ? <Register /> : <Navigate to="/home" replace /> }, { path: '/home', element: authState ? <Form /> : <Navigate to="/login" replace /> } ]) return ( <RouterProvider router={router} /> ) }
内容的提问来源于stack exchange,提问作者Sairam
相关产品推荐
相关产品推荐

