如何在同一页面内使用React Routes实现局部内容渲染
问题描述
希望在首页中间添加子菜单,点击每个链接时在其下方加载对应内容。使用React-Router实现后,出现的问题是会渲染新页面,但我希望在首页的局部区域渲染。
预期效果截图



当前代码
子菜单数据定义
// 用对象数组来避免组件里写太多列表代码 export const dataSubMenu = [ { id: 1, name: "Landing Page", boton: "Comienza Hoy", Link: "landing" }, { id: 2, name: "Tienda Web", boton: "Comienza Hoy", Link: "tienda" }, { id: 3, name: "Web Empresarial", boton: "Comienza Hoy", Link: "webEmpresarial" }, { id: 4, name: "Web Hosting", boton: "Comienza Hoy", Link: "webHosting" }, { id: 5, name: "Mas Servicios", boton: "Comienza Hoy", Link: "otrosServicios" }, ]
SubMenu组件
/* 子菜单组件 */ import { dataSubMenu } from "./dataSubMenu"; import './subMenu.css'; import { NavLink } from "react-router-dom"; export const SubMenu = () => { return ( <> <section className="conteiner__sub__menu"> <ul> {dataSubMenu.map((item) => ( <li key={item.id}> <NavLink className='menu__Item--a' to={item.Link}> <h3>{item.name}</h3> </NavLink> </li> ))} </ul> </section> </> ) }
App组件
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import { createContext, useState } from "react"; import { Header } from "./components/headers/header"; import { HomePage } from "./routes/home"; import { ProductsPage } from "./routes/products"; import { MasServiciosPage } from "./routes/masServicios"; import { NosotrosPage } from "./routes/nosotros"; import { ContactPage } from "./routes/contact"; import { NotFoundPage } from "./routes/notFoundPage"; import "./app.css"; import { LandingPage } from "./routes/landing"; import { TiendaPage } from "./routes/tienda"; import { WebEmpresarialPage } from "./routes/webEmpresarial"; import { WebHostingPage } from "./routes/webHosting"; import { OtrosServiciosPage } from "./routes/otrosServicios"; export const ThemeContext = createContext(null); function App() { const [theme, setTheme] = useState("light"); let html = document.querySelector("html"); html.setAttribute("data-theme", theme); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <> <Router> {/* 所有在<Routes>外的内容作为布局 */} <Header /> <Routes> {/* 定义要使用的路由 */} <Route path="/" element={<HomePage />} /> <Route path="/home" element={<HomePage />} /> <Route path="/products" element={<ProductsPage />} /> <Route path="/masServicios" element={<MasServiciosPage />} /> <Route path="/contact" element={<ContactPage />} /> <Route path="/nosotros" element={<NosotrosPage />} /> {/* 下面是我为子菜单写的代码 */} <Route path="/landing" element={<LandingPage />} /> <Route path="/tienda" element={<TiendaPage />} /> <Route path="/webEmpresarial" element={<WebEmpresarialPage />} /> <Route path="/webHosting" element={<WebHostingPage />} /> <Route path="/otrosServicios" element={<OtrosServiciosPage />} /> <Route path="*" element={<NotFoundPage />} /> </Routes> </Router> </> </ThemeContext.Provider> ); } export default App;
解决方法
要实现首页局部加载子菜单内容,需要使用React-Router的嵌套路由,将子页面作为首页的子路由,而非独立路由。具体步骤如下:
1. 修改App组件的路由结构,嵌套子页面路由
将原来独立的子路由改为HomePage的子路由,通过Route的children属性实现嵌套:
// App.js 中的Routes部分修改为: <Routes> <Route path="/" element={<HomePage />}> {/* 可选:访问首页根路径时默认渲染的子页面 */} <Route index element={<LandingPage />} /> {/* 子菜单对应的子路由 */} <Route path="landing" element={<LandingPage />} /> <Route path="tienda" element={<TiendaPage />} /> <Route path="webEmpresarial" element={<WebEmpresarialPage />} /> <Route path="webHosting" element={<WebHostingPage />} /> <Route path="otrosServicios" element={<OtrosServiciosPage />} /> </Route> {/* 其他独立路由保持不变 */} <Route path="/products" element={<ProductsPage />} /> <Route path="/masServicios" element={<MasServiciosPage />} /> <Route path="/contact" element={<ContactPage />} /> <Route path="/nosotros" element={<NosotrosPage />} /> <Route path="*" element={<NotFoundPage />} /> </Routes>
2. 调整SubMenu的NavLink路径(确保路由匹配)
由于子路由嵌套在HomePage下,NavLink的to属性可以使用绝对路径或相对路径(如果SubMenu是HomePage的子组件,相对路径更灵活):
// SubMenu.js 中的NavLink修改为: <NavLink className='menu__Item--a' to={`/${item.Link}`}> <h3>{item.name}</h3> </NavLink> // 若SubMenu是HomePage的子组件,直接用相对路径即可: // <NavLink className='menu__Item--a' to={item.Link}>
3. 在HomePage中添加Outlet渲染子内容
在HomePage的JSX里,子菜单下方的位置引入Outlet组件,这是React-Router专门用来渲染子路由内容的容器:
// HomePage.js import { Outlet } from 'react-router-dom'; import { SubMenu } from '../components/subMenu'; // 根据实际路径调整 export const HomePage = () => { return ( <div className="home-page"> {/* 首页原有内容 */} <h1>首页标题</h1> {/* 子菜单 */} <SubMenu /> {/* 子内容渲染区域 */} <div className="sub-content-area"> <Outlet /> </div> {/* 首页其他内容 */} </div> ); };
修改完成后,点击子菜单链接时,页面不会整体跳转,只会在HomePage的Outlet区域渲染对应的子页面内容,实现局部加载的效果。
内容的提问来源于stack exchange,提问作者Matias
相关产品推荐
相关产品推荐

