当前位置: 首页 > news >正文

React Router v6 核心组件

下面,我们来系统的梳理关于 React Router v6 核心组件 的基本知识点:


一、BrowserRouter - 路由容器组件

1.1 核心功能与作用

<BrowserRouter> 是 React Router 的基础容器组件,提供基于 HTML5 History API 的路由功能:

  • 启用客户端路由:实现无刷新页面导航
  • 管理浏览历史:支持前进/后退操作
  • 提供路由上下文:为子组件提供路由信息
  • 同步URL与UI:URL变化时自动更新组件树

1.2 使用方式

// 入口文件 index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<React.StrictMode><BrowserRouter><App /></BrowserRouter></React.StrictMode>
);

1.3 关键配置项

<BrowserRouterbasename="/app" // 基础路径(适用于子目录部署)window={window} // 自定义window对象(SSR时使用)
>{/* 应用内容 */}
</BrowserRouter>

1.4 实现原理

使用
创建
监听
触发
通知
BrowserRouter
history库
history对象
popstate事件
路由更新
Route组件

二、Routes - 路由配置中心

2.1 核心功能与作用

<Routes> 是 v6 版本引入的核心组件,取代了 v5 中的 <Switch>

  • 智能路由匹配:自动选择最佳匹配的路由
  • 嵌套路由支持:简化路由层级结构
  • 相对路径处理:自动继承父路由路径
  • 路由优先级管理:不再依赖顺序(但仍建议合理排序)

2.2 基本使用

import { Routes, Route } from 'react-router-dom';function App() {return (<Routes><Route path="/" element={<HomePage />} /><Route path="about" element={<AboutPage />} /><Route path="products" element={<ProductsPage />} /></Routes>);
}

2.3 嵌套路由模式

<Routes><Route path="/" element={<Layout />}>{/* 嵌套路由自动继承父路径 */}<Route index element={<Home />} /><Route path="dashboard" element={<Dashboard />} /><Route path="settings" element={<Settings />} /></Route>
</Routes>// Layout组件中定义出口
function Layout() {return (<div><Header /><main><Outlet /> {/* 子路由在此渲染 */}</main><Footer /></div>);
}

2.4 路由匹配规则

模式匹配路径说明
/根路径精确匹配
about/about相对路径
users/:id/users/123路径参数
posts/*/posts/2023/react通配符匹配
docs/:section?/docs 或 /docs/getting-started可选参数

三、Route - 路由配置单元

3.1 核心属性解析

属性类型说明必需
pathstring路由匹配路径否(index路由不需要)
elementReactNode匹配时渲染的组件
indexboolean标记为索引路由
caseSensitiveboolean是否区分大小写

3.2 索引路由(Index Routes)

<Route path="/teams" element={<Teams />}>{/* 当URL为/teams时渲染TeamList */}<Route index element={<TeamList />} /><Route path=":teamId" element={<TeamDetail />} />
</Route>

3.3 动态路由参数

<Route path="users/:userId" element={<UserProfile />} />// 在UserProfile组件中获取参数
import { useParams } from 'react-router-dom';function UserProfile() {const { userId } = useParams();return <div>用户ID: {userId}</div>;
}

3.4 布局路由模式

<Routes>{/* 公共布局 */}<Route element={<MainLayout />}><Route path="/" element={<Home />} /><Route path="about" element={<About />} /></Route>{/* 独立布局 */}<Route element={<AuthLayout />}><Route path="login" element={<Login />} /><Route path="register" element={<Register />} /></Route>
</Routes>

四、路由导航与编程控制

4.1 声明式导航(Link组件)

import { Link } from 'react-router-dom';function Navigation() {return (<nav><Link to="/">首页</Link><Link to="/about">关于</Link><Link to="/users/123">用户资料</Link>{/* 高级用法 */}<Link to="/dashboard"state={{ from: location.pathname }} // 传递状态replace={true} // 替换历史记录reloadDocument={false} // 是否整页刷新>控制面板</Link></nav>);
}

4.2 编程式导航(useNavigate)

import { useNavigate } from 'react-router-dom';function LoginForm() {const navigate = useNavigate();const handleSubmit = async (e) => {e.preventDefault();try {await login(credentials);// 导航到目标页面navigate('/dashboard');// 相对路径导航navigate('../success');// 带状态导航navigate('/profile', { state: { newUser: true } });// 替换历史记录navigate('/home', { replace: true });// 前进/后退navigate(-1); // 后退一页navigate(2);  // 前进两页} catch (error) {console.error('登录失败', error);}};return (<form onSubmit={handleSubmit}>{/* 表单内容 */}</form>);
}

4.3 获取路由信息

import { useLocation, useSearchParams,useRouteMatch 
} from 'react-router-dom';function ProductPage() {const location = useLocation();const [searchParams, setSearchParams] = useSearchParams();// 获取查询参数const category = searchParams.get('category');const sort = searchParams.get('sort');// 获取路径匹配信息(v6中较少使用)const match = useRouteMatch();// 更新查询参数const updateSort = (newSort) => {setSearchParams({ ...Object.fromEntries(searchParams), sort: newSort });};return (<div><h2>产品列表</h2><p>当前分类: {category}</p><button onClick={() => updateSort('price')}>按价格排序</button>{/* 显示完整路径信息 */}<pre>{JSON.stringify(location, null, 2)}</pre></div>);
}

五、高级路由模式

5.1 路由守卫(鉴权)

// src/components/AuthRoute.jsx
import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';function AuthRoute({ children, roles = [] }) {const { user, isAuthenticated } = useAuth();const location = useLocation();if (!isAuthenticated) {// 未登录重定向到登录页,并保存来源位置return <Navigate to="/login" state={{ from: location }} replace />;}if (roles.length > 0 && !roles.some(role => user.roles.includes(role))) {// 无权限访问return <Navigate to="/unauthorized" replace />;}return children;
}// 使用
<Routepath="/admin"element={<AuthRoute roles={['admin']}><AdminDashboard /></AuthRoute>}
/>

5.2 路由懒加载

import { lazy, Suspense } from 'react';const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Contact = lazy(() => import('./pages/Contact'));function App() {return (<Suspense fallback={<div>加载中...</div>}><Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} /></Routes></Suspense>);
}

5.3 错误边界处理

<Route path="/dashboard"element={<Dashboard />}errorElement={<ErrorBoundary />} // 组件级错误边界
><Route path="analytics"element={<Analytics />}errorElement={<AnalyticsError />} // 嵌套错误边界/>
</Route>

六、实践与项目结构

6.1 推荐项目结构

src/
├── components/
│   ├── layout/
│   │   ├── MainLayout.jsx
│   │   └── AuthLayout.jsx
│   └── ui/
│       ├── Header.jsx
│       └── Footer.jsx
├── pages/
│   ├── Home.jsx
│   ├── About.jsx
│   ├── Dashboard.jsx
│   └── ...
├── routes/
│   ├── index.js        # 主路由配置
│   ├── publicRoutes.js # 公开路由
│   └── privateRoutes.js # 需要认证的路由
├── App.js
└── index.js

6.2 集中式路由配置

// src/routes/index.js
import { lazy } from 'react';
import AuthLayout from '../components/layout/AuthLayout';
import MainLayout from '../components/layout/MainLayout';
import AuthRoute from '../components/AuthRoute';const Home = lazy(() => import('../pages/Home'));
const Dashboard = lazy(() => import('../pages/Dashboard'));
const Login = lazy(() => import('../pages/Login'));const routes = [{path: '/',element: <MainLayout />,children: [{ index: true, element: <Home /> },{ path: 'dashboard',element: <AuthRoute><Dashboard /></AuthRoute>},// ...其他受保护路由]},{element: <AuthLayout />,children: [{ path: 'login', element: <Login /> },{ path: 'register', element: <Register /> },{ path: 'forgot-password', element: <ForgotPassword /> },]},{path: '*',element: <NotFoundPage />}
];export default routes;// src/App.js
import { useRoutes } from 'react-router-dom';
import routes from './routes';function App() {return useRoutes(routes);
}export default App;

七、常见问题与解决方案

7.1 路由匹配问题

问题:路由不匹配或匹配错误
解决

// 确保使用正确的路径格式
<Route path="users/:id" /> // 匹配 /users/123// 使用通配符处理未匹配路由
<Route path="*" element={<NotFound />} />// 检查嵌套路由的Outlet位置

7.2 导航循环问题

问题:鉴权逻辑导致无限重定向
解决

// 在AuthRoute组件中添加重定向状态检查
if (location.pathname === '/login') {return children;
}

7.3 滚动恢复问题

问题:页面切换后滚动位置不正确
解决

// 创建自定义滚动恢复组件
function ScrollToTop() {const { pathname } = useLocation();useEffect(() => {window.scrollTo(0, 0);}, [pathname]);return null;
}// 在路由配置中使用
<Routes><Route element={<><ScrollToTop /><MainLayout /></>}>{/* ...路由配置 */}</Route>
</Routes>

7.4 查询参数处理

问题:获取和更新查询参数
解决

const [searchParams, setSearchParams] = useSearchParams();// 获取参数
const page = searchParams.get('page');// 更新参数
const updatePage = (newPage) => {searchParams.set('page', newPage);setSearchParams(searchParams);
};// 保留现有参数添加新参数
setSearchParams({ ...Object.fromEntries(searchParams), sort: 'asc' });

八、总结

8.1 React Router v6 核心概念

组件功能关键特性
BrowserRouter路由容器提供路由上下文、历史管理
Routes路由配置中心智能匹配、嵌套路由支持
Route路由单元路径映射、动态参数、布局控制

8.2 实践总结

  1. 合理组织路由:采用集中式配置管理路由
  2. 嵌套路由优化:使用布局组件和Outlet实现UI复用
  3. 路由守卫实现:通过高阶组件保护敏感路由
  4. 懒加载提升性能:结合Suspense实现代码分割
  5. 错误边界处理:提供友好的错误恢复体验

8.3 核心API速查

API功能使用场景
useNavigate编程导航表单提交后跳转
useParams获取路径参数动态路由数据加载
useLocation获取位置信息页面跟踪、路由守卫
useSearchParams操作查询参数筛选、排序功能
Outlet渲染嵌套路由布局组件中
http://www.lryc.cn/news/602926.html

相关文章:

  • Linux进程概念(五)进程地址空间
  • 吃透 lambda 表达式(匿名函数)
  • 关闭 UniGetUI 自动 Pip 更新,有效避免 Anaconda 环境冲突教程
  • 3.DRF视图和路由
  • sqlite3学习---基础知识、增删改查和排序和限制、打开执行关闭函数
  • SpringBoot数学实例:高等数学实战
  • (二)Eshop(RabbitMQ手动)
  • 【计算机网络】OSI七层模型
  • Qt项目中使用 FieldManager 实现多进程间的字段数据管理
  • EXCEL怎么使用数据透视表批量生成工作表
  • 十七、K8s 可观测性:全链路追踪
  • django 按照外键排序
  • 未授权访问
  • 项目如何按时交付?重点关注的几点
  • 进程间通信————system V 共享内存
  • Python day27
  • 在rsync + inotify方案中,如何解决海量小文件同步效率问题?
  • 从视觉到智能:RTSP|RTMP推拉流模块如何助力“边缘AI系统”的闭环协同?
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘nbconvert’问题
  • Java设计模式-通俗举例
  • 铜金矿数据分组优化系统设计与实现
  • 扩展和插件功能
  • 网络 编程
  • C#_运算符重载 operator
  • Joint.cpp - OpenExo
  • Windows 11 下 Anaconda 命令修复指南及常见问题解决
  • MCP error -32000: Connection closed
  • ESP32学习-按键中断
  • 【unitrix】 6.20 非零整数特质(non_zero.rs)
  • Laravel 分页方案整理