如何在React Router DOM中创建路由地址变化时不更新的组件
在react-router-dom中创建路由切换时不改变的固定组件
要实现路由地址变化时保持不变且能使用useNavigate的组件,核心思路是用嵌套路由+布局组件,把固定组件放在布局里,让其他页面路由作为布局的子路由。这样布局里的固定组件不会随路由切换重新渲染,同时因为处于RouterProvider的上下文范围内,能正常调用useNavigate。
步骤1:创建布局组件
先写一个包含固定导航的布局组件,用<Outlet />作为子路由内容的占位符:
import { Outlet } from 'react-router-dom'; import Navbar from './Navbar'; // 你的导航组件 function MainLayout() { // 这里可以添加其他固定元素,比如页脚 return ( <div className="app-container"> {/* 导航组件,路由切换时不会重新渲染 */} <Navbar /> {/* 子路由内容会渲染在这里 */} <Outlet /> </div> ); } export default MainLayout;
你的导航组件Navbar可以正常使用useNavigate,因为它处于路由上下文内:
import { useNavigate } from 'react-router-dom'; function Navbar() { const navigate = useNavigate(); const goToHome = () => { navigate('/'); }; return ( <nav> <button onClick={goToHome}>首页</button> {/* 其他导航元素 */} </nav> ); } export default Navbar;
步骤2:修改路由配置
把原来的所有路由都改成MainLayout的子路由,根路由指向布局组件:
import { createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom'; import MainLayout from './MainLayout'; import Home from './Home'; import ServiceUnavailable from './ServiceUnavailable'; import NotFoundPage from './NotFoundPage'; const router = createBrowserRouter( createRoutesFromElements( <Route path="/" element={<MainLayout />}> {/* 子路由:这些页面会渲染在MainLayout的Outlet里 */} <Route index element={<Home />} /> <Route path="503" element={<ServiceUnavailable />} /> <Route path="*" element={<NotFoundPage />} /> </Route> ) ); return <RouterProvider router={router} />;
方案原理
<Outlet />是react-router提供的子路由占位符,路由切换时只有Outlet内的内容会更新,布局里的Navbar等固定组件不会重新渲染。- 布局组件和导航组件都在
RouterProvider的上下文范围内,所以useNavigate能正常获取路由导航实例,不会报错。
关于BrowserRouter的useEffect错误
如果之前用BrowserRouter时出现useEffect错误,大概率是组件挂载时路由上下文还未初始化导致的。而createBrowserRouter+RouterProvider是react-router v6推荐的写法,路由实例提前创建完成,能避免这类时机问题。
内容的提问来源于stack exchange,提问作者chebread
相关产品推荐
相关产品推荐

