React Router嵌套路由失效:访问/es/products等路由跳转至首页
问题排查与解决方案
核心原因:父路由未渲染嵌套路由出口
React Router v6 中,嵌套路由的父组件必须通过 <Outlet /> 组件承载子路由的内容。你的代码里,HomeComponent 作为 :lang 路由的渲染组件,没有引入并使用 <Outlet />,导致访问 /es/products 等嵌套路径时,子路由组件无法渲染,看起来像是仍停留在 HomeComponent。
修复步骤
1. 在 HomeComponent 中添加 <Outlet />
在 HomeComponent 文件中导入 Outlet,并在合适位置放置它,用于渲染嵌套路由内容:
// pages/home.jsx import { Outlet } from 'react-router-dom'; function HomeComponent() { return ( <div> {/* 原有 Home 页面内容 */} <h1>Home Page</h1> {/* 嵌套路由的组件会在此处渲染 */} <Outlet /> </div> ); } export default HomeComponent;
2. 清理冗余路由规则
代码中存在两条重复的根路径重定向规则,可合并为一条并添加 replace 属性优化浏览器历史记录:
// 替换原有的两条根路径路由 <Route path="/" element={<Navigate to="/es/" replace />} />
3. 调整路由匹配顺序与NotFound规则
将兜底路由放在所有具体路由之后,确保只有未匹配到的路径才会触发重定向或404:
// 替换原有的NotFound和UserRedirect路由位置 <Route path="/:lang/error" element={<NotFound />} /> <Route path="*" element={<UserRedirect />} />
4. 完整修复后的路由代码
import { Suspense, useEffect } from "react"; import LoadingComponent from "./components/ui/Loader"; import { BrowserRouter as Router, Routes, Route, useNavigate, Navigate, } from "react-router-dom"; import HomeComponent from "./pages/home"; import ProductsComponent from "./pages/products"; import ProductPayFairComponent from "./pages/payfair"; import Providers from "./components/Providers"; import NotFound from "./pages/404"; import "./lib/i18n"; function UserRedirect() { const navigate = useNavigate(); useEffect(() => { const defaultLanguage = "es"; const redirectPath = `/${defaultLanguage}/`; navigate(redirectPath, { replace: true }); // 添加replace优化历史记录 }, [navigate]); return null; } function App() { return ( <Suspense fallback={<LoadingComponent isLoading={true} />}> <Providers> <Router> <Routes> <Route path="/" element={<Navigate to="/es/" replace />} /> {/* 带嵌套路由的语言路由 */} <Route path=":lang" element={<HomeComponent />}> <Route path="products" element={<ProductsComponent/>}> <Route path="payfair" element={<ProductPayFairComponent />} /> </Route> </Route> <Route path="/:lang/error" element={<NotFound />} /> <Route path="*" element={<UserRedirect />} /> </Routes> </Router> </Providers> </Suspense> ); } export default App;
可选优化:拆分首页与布局路由
如果不需要在嵌套路由页面显示 HomeComponent 的内容,可以将语言路由改为纯布局组件,单独拆分首页路由:
// 新增布局组件 function LanguageLayout() { return <Outlet />; } // 修改路由结构 <Route path=":lang" element={<LanguageLayout />}> <Route index element={<HomeComponent />} /> {/* 匹配 /:lang 路径 */} <Route path="products" element={<ProductsComponent/>}> <Route path="payfair" element={<ProductPayFairComponent />} /> </Route> </Route>
这样访问 /es/ 时渲染 HomeComponent,访问 /es/products 时仅渲染 ProductsComponent,不会包含首页内容。
内容的提问来源于stack exchange,提问作者Diego Peña Vicente
相关产品推荐
相关产品推荐

