React嵌套路由跳转异常求助:useNavigate与Router使用问题
问题描述
我开发的系统加载后需要用户登录,登录验证通过后进入带有多个菜单的页面(初始无菜单,登录后显示)。我使用Router、useNavigate实现了嵌套路由,但点击菜单显示对应组件时,页面会自动返回菜单根目录。以下是相关代码,请问问题出在哪里?
App.js
import React, { useEffect, useState } from "react"; import { Navigate, Route, Routes, useNavigate } from "react-router-dom"; import "./App.css"; import Container from "./container/Container"; import Router from "./components/clinic/router/Router"; import Message from "./components/clinic/pages/message/Message"; import Mytasks from "./components/clinic/pages/mytasks/Mytasks"; import Members from "./components/clinic/pages/members/Members"; import Calendar from "./components/clinic/pages/calendar/Calendar"; function App() { const [IsLoggedIn, setIsLoggedIn] = useState(false); const navigate = useNavigate(); useEffect(() => { if (!IsLoggedIn) { navigate("/"); } else { navigate("clinic"); } }, [navigate, IsLoggedIn]); return ( <React.Fragment> <Routes> <Route path="/" element={<Container setIsLoggedIn={setIsLoggedIn} />} /> <Route path="/clinic" element={<Router />}> <Route index element={<Message />} /> <Route path="mytasks" element={<Mytasks />} /> <Route path="members" element={<Members />} /> <Route path="calendar" element={<Calendar />} /> <Route path="*" element={<Navigate to="/" />} /> </Route> <Route path="*" element={<Navigate to="/" />} /> </Routes> </React.Fragment> ); } export default App;
Router.jsx
<Link to="/clinic">Message</Link> <Link to="/clinic/mytasks/"> My Tasks </Link> <Link to="/clinic/members"> Members </Link> <Link to="/clinic/calendar"> Calendar </Link> <Outlet />
问题原因与解决方法
核心问题
问题出在App组件的useEffect钩子上:每当IsLoggedIn状态变化时,这个钩子就会触发强制导航。当你点击菜单进入/clinic/mytasks这类子路由时,组件重新渲染,IsLoggedIn仍为true,useEffect就会执行navigate("clinic"),直接把页面重定向回/clinic根目录,刚进入的子路由被覆盖。
另外,Router.jsx中/clinic/mytasks/多了末尾斜杠,虽不是直接原因,但可能引发路由匹配异常,建议统一格式。
解决步骤
- 修改useEffect逻辑:只在登录状态从未登录变为已登录时执行导航,而非每次状态变化都触发:
useEffect(() => { // 仅在登录状态切换为已登录时,导航到clinic页面 if (IsLoggedIn) { navigate("/clinic", { replace: true }); } }, [navigate, IsLoggedIn]);
添加{ replace: true }是为了避免登录后点击返回按钮回到登录页,优化体验。
- 修正Router.jsx的路由链接:去掉
/clinic/mytasks/末尾的斜杠,保持链接格式一致:
<Link to="/clinic">Message</Link> <Link to="/clinic/mytasks"> My Tasks </Link> <Link to="/clinic/members"> Members </Link> <Link to="/clinic/calendar"> Calendar </Link> <Outlet />
- 优化嵌套路由兜底规则:嵌套路由里的
path="*"不要直接跳转到/,改为跳转到当前嵌套路由的首页,避免用户在子路由误输路径直接回到登录页:
// 将嵌套路由中的兜底路由修改为 <Route path="*" element={<Navigate to="/clinic" />} />
这样修改后,点击菜单进入子路由时,useEffect不会再强制导航回根目录,页面就能正常停留在对应子路由组件中了。
内容的提问来源于stack exchange,提问作者Ramin Maghsoudi
相关产品推荐
相关产品推荐

