如何在React子组件的Routes中定义生效的嵌套路由?
解决嵌套路由加载失败的两种方法
方法一:用Outlet实现布局复用(推荐)
这是React Router v6官方推荐的嵌套路由写法,把Accounting做成布局组件,专门负责渲染Navbar、Sidebar这些公共部分,子页面内容用Outlet来承接,结构更清晰,也方便后续加新的子路由。
1. 修改App.js的路由结构
把原来的/dashboard/accounting改成父路由,把add、remove这些子路由直接挂在下面:
import Accounting from "./pages/Accounting/Accounting"; import AccountingAll from "./components/Accounting/AccountingAll"; import forExampleREmove from "./components/Accounting/forExampleREmove"; // 注意组件路径要正确 const App = () => { return ( <BrowserRouter> <Routes> <Route path="/dashboard"> <Route index element={<Dashboard />} /> <Route path="add-test" element={<Tests />} /> {/* 将accounting设为父路由,子路由定义在此 */} <Route path="accounting" element={<Accounting />}> <Route index element={<AccountingAll />} /> {/* 匹配/dashboard/accounting */} <Route path="add" element={<AccountingAll />} /> {/* 匹配/dashboard/accounting/add */} <Route path="remove" element={<forExampleREmove />} /> {/* 匹配/dashboard/accounting/remove */} </Route> </Route> <Route path="login" element={<Login />} /> <Route path="stepper" element={<Stepper />} /> <Route path="verify" element={<Verify />} /> </Routes> </BrowserRouter> ); };
2. 修改Accounting组件,用Outlet渲染子内容
删掉Accounting里自行定义的Routes和Route,替换为Outlet即可:
import React from "react"; import Navbar from "../shared/Navbar"; import Sidebar from "../shared/Sidebar"; import SettingsPanel from "../shared/SettingsPanel"; import Footer from "../shared/Footer"; import { Outlet } from "react-router-dom"; // 导入Outlet const Accounting = () => { return ( <> <div className="container-scroller rtl"> <Navbar /> <div className="container-fluid page-body-wrapper"> <Sidebar /> <div className="main-panel"> <div className="content-wrapper"> {/* 子路由的内容会自动渲染到Outlet的位置 */} <Outlet /> <SettingsPanel /> </div> <Footer /> </div> </div> </div> </> ); }; export default Accounting;
方法二:直接修正Accounting里的路由路径(不推荐,仅应急使用)
如果不想改动App.js的路由结构,只需把Accounting里的路由路径改成相对路径——去掉路径开头的/,因为带/的是绝对路径,会从根目录开始匹配,自然找不到/dashboard/accounting下的子路由。
修改后的Accounting组件:
import React from "react"; import Navbar from "../shared/Navbar"; import Sidebar from "../shared/Sidebar"; import SettingsPanel from "../shared/SettingsPanel"; import Footer from "../shared/Footer"; import AccountingAll from "../../components/Accounting/AccountingAll"; import forExampleREmove from "../../components/Accounting/forExampleREmove"; import { Routes, Route } from "react-router-dom"; // 无需重复导入BrowserRouter const Accounting = () => { return ( <> <div className="container-scroller rtl"> <Navbar /> <div className="container-fluid page-body-wrapper"> <Sidebar /> <div className="main-panel"> <div className="content-wrapper"> <Routes> {/* 去掉路径开头的斜杠,改为相对路径 */} <Route path="add" element={<AccountingAll />} /> <Route path="remove" element={<forExampleREmove />} /> {/* 可选:添加index路由,匹配/dashboard/accounting本身 */} <Route index element={<AccountingAll />} /> </Routes> <SettingsPanel /> </div> <Footer /> </div> </div> </div> </> ); }; export default Accounting;
关键注意点
- React Router v6中,路径开头带
/是绝对路径(从根目录匹配),不带则是相对当前父路由的路径,别搞混。 - 优先选择方法一,后续新增子路由只需在App.js中添加即可,无需修改布局组件,维护更省心。
- 检查组件导入路径是否正确,比如
forExampleREmove的路径要和实际文件位置对应,避免因路径错误导致组件无法加载。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

