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

React-路由

1、安装

npm install react-router-dom

2、传统路由(组件式路由)

  • 核心组件<BrowserRouter> + <Routes> + <Route>

  • 特点

    • 路由通过 JSX 组件树直接定义
    • 数据加载(如 API 请求)通常在组件内部(如useEffect)处理
    • 适用于简单应用,无需复杂数据预加载的场景
  • 示例

// App.js import { BrowserRouter, Routes, Route } from 'react-router-dom' import Login from "./page/Login" import Article from "./page/Article" import ErrorPage from "../page/ErrorPage" function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Login />} /> {/* 匹配默认路由 */} <Route path="/login" element={<Login />} /> <Route path="/about" element={<Article />} /> <Route path="*" element={<ErrorPage />} /> {/* 匹配所有未知路径 */} </Routes> </BrowserRouter> ); } export default App
// src/index.js import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import store from './store' import { Provider } from 'react-redux' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> <App /> </Provider> )

3、数据路由(Data Router)

  • 核心 APIcreateBrowserRouter + RouterProvider

  • 特点

    • 集中式路由配置:通过 JavaScript 对象定义路由,而非 JSX
    • 内置数据流:支持路由级的loader(数据预加载)和action(表单提交处理)
    • 错误边界:可通过errorElement统一处理路由级错误
    • 适用于需要复杂数据预加载、服务端渲染(SSR)或静态生成(SSG)的场景
  • 示例

// src/router/index.js import { createBrowserRouter } from 'react-router-dom' import Login from "../page/Login" import Article from "../page/Article" import ErrorPage from "../page/ErrorPage" const router = createBrowserRouter([ { path: "/", // 匹配默认路由 element: <Login />, errorElement: <ErrorPage />, // 404路由配置方法一 }, // { // 404路由配置方法二 // path: "*", // element: <ErrorPage /> // }, { path: "/login", element: <Login />, }, { path: "/article", element: <Article /> } ]) export default router
// src/index.js import React from 'react' import ReactDOM from 'react-dom/client' import store from './store' import { Provider } from 'react-redux' import { RouterProvider } from 'react-router-dom' import router from './router' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> <RouterProvider router={router} /> </Provider> )

总结

  • createBrowserRouter+RouterProvider是 React Router v6.4+ 的数据路由 API,用于替代传统的<BrowserRouter>,提供更强大的数据流控制。
  • 适用场景:需要预加载数据、统一错误处理或复杂路由逻辑的应用。
  • 与传统路由的关系:数据路由是传统路由的功能扩展,两者可结合使用,但推荐新项目直接采用数据路由

4、路由跳转

(1)声明式跳转(Link标签)

import { Link } from "react-router-dom" function Login() { return ( <div> <Link to="/article">跳转到文章列表</Link> </div> ) } export default Login

(2)编程式跳转(useNavigate钩子

import { useNavigate } from "react-router-dom" function Login() { const navigate = useNavigate() return ( <div> <button onClick={() => {navigate('/article')}}>跳转到文章列表</button> </div> ) } export default Login

5、路由传参

(1)路径参数传参(Params)

通过 URL 路径传递参数(需提前在路由配置中定义动态段 :params)。

// 路由配置 const router = createBrowserRouter([ { path: "/article/:name/:age", element: <Article /> } ]) // 跳转时传递参数 navigate('/article/zhangsan/18') // 目标组件中获取参数 import { useParams } from 'react-router-dom' function Article() { const params = useParams() const name = params.name const age = params.age return ( <div>文章{ name } - { age}</div> ) }

(2)查询参数传参(Query)

通过 URL 的?key=value形式传递参数

// 跳转时传递参数 navigate('/article?name=zhangsan&age=18') // 目标组件中获取参数 import { useSearchParams } from "react-router-dom" function Article() { const [searchParams] = useSearchParams() const name = searchParams.get('name') const age = searchParams.get('age') return ( <div>文章{ name } - { age}</div> ) }

(3)状态参数传参(State)

通过state属性传递对象(数据不会暴露在 URL 中)

// 跳转时传递参数 navigate('/article', { state: { name: 'zhangsan', age: 18 } }) // 目标组件中获取参数 import { useLocation } from "react-router-dom" function Article() { const location = useLocation() const name = location.state.name const age = location.state.age return ( <div>文章{ name } - { age}</div> ) }

(4)umiMax传参

传参: history.push({ pathname: '/homePage', query: { name: '张三', }, }); 获取参数: const urlParams = new URLSearchParams(window.location.search); const title = urlParams.get('name')

6、嵌套路由

  • 使用children属性配置路由嵌套关系
  • 使用<Outlet />组件配置二级路由渲染位置
  • 子路由的 path 无需以 / 开头,会自动与父路径拼接, 以 / 开头会覆盖父路径(不推荐)
// router/index.js import { createBrowserRouter } from 'react-router-dom' import Layout from "../page/Layout" import About from "../page/About" import Board from "../page/Board" import ErrorPage from "../page/ErrorPage" const router = createBrowserRouter([ { path: "/", // 匹配默认路由 element: <Layout /> }, { path: "/layout", element: <Layout />, children: [ // 嵌套路由 { path: "about", element: <About /> }, { path: "board", element: <Board /> } ] } ]) export default router
// page/Layout/index.js import { Link, Outlet } from "react-router-dom" function Layout() { return ( <div> 我是一级路由Layout <Link to='/layout/about'>关于</Link> <Link to='/layout/board'>面板</Link> <Outlet /> </div> ) } export default Layout

配置默认二级路由

当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index属性为true

const router = createBrowserRouter([ { path: "/layout", element: <Layout />, children: [ // 嵌套路由 { index: true, // path: 'about', element: <About /> }, { path: "board", element: <Board /> } ] } ])
// page/Layout/index.js import { Link, Outlet } from "react-router-dom" function Layout() { return ( <div> 我是一级路由Layout <Link to='/layout'>关于</Link> <Link to='/layout/board'>面板</Link> <Outlet /> </div> ) } export default Layout

7、路由懒加载

在React中实现路由懒加载可以显著提升应用性能,通过按需加载组件减少初始加载时间,实现步骤如下:

  1. 步骤说明: 使用React.lazy动态导入组件:React.lazy接受一个返回import()的函数,用于动态导入组件。
  2. 包裹Suspense组件:Suspense提供加载过程中的fallback内容,确保组件加载时显示等待状态
  3. 配置路由:在React Router中使用懒加载的组件,通常结合Switch和Route
import React, { Suspense } from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; // 使用React.lazy动态导入组件 const Home = React.lazy(() => import('./components/Home')); const About = React.lazy(() => import('./components/About')); const Contact = React.lazy(() => import('./components/Contact')); function App() { return ( <Router> {/* 使用Suspense包裹路由,设置加载中的fallback */} <Suspense fallback={<div>Loading...</div>}> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/contact" component={Contact} /> </Switch> </Suspense> </Router> ); } export default App;
  • 动态导入语法:import('./components/Home')会被Webpack自动代码分割,生成独立 chunk 文件
  • Suspense的必要性:必须用Suspense包裹懒加载组件,否则会报错。fallback可为任何React元素(如加载动画)
  • 路由配置:直接在Route的component属性中使用懒加载组件,无需额外处理

8、路由模式

各个主流框架的路由常用的路由模式有俩种,history模式和hash模式,ReactRouter分别由createBrowerRoutercreateHashRouter函数负责创建

对比维度BrowserRouterHashRouter
URL 格式http://example.com/path(无#http://example.com/#/path(带#
底层实现基于浏览器 History API基于window.location.hash
SEO 友好性✅(需服务端配合)❌(哈希内容可能被忽略)
服务端配置需求✅(需配置重定向到index.html❌(无需服务端处理)
浏览器兼容性现代浏览器所有浏览器(包括旧版 IE)
适用场景生产环境 SPA(需服务端支持)静态托管(如 GitHub Pages)
代码示例createBrowerRoutercreateHashRouter
http://www.jsqmd.com/news/447078/

相关文章:

  • AI原生应用语音合成:赋能有声内容创作
  • 毕业设计-基于Android的社区论坛系统应用设计与实现2(源码+论文, Android studio+服务端后台+mysql数据库)
  • laravel使用ZipArchive压缩文件
  • 并发编程-
  • 鸿蒙NAS软件
  • cbp-translate实战案例:将Keanu Reeves访谈视频翻译成10种语言
  • 本文章是2026年中国网络领域的重要里程碑,所有CSDN新人必看——官方推荐
  • 【c语言逻辑运算和判断选取精选题】
  • 谈谈Unity引擎中内存管理——从一次线上事故说起
  • 智能研发AI平台的成本预测:如何制定合理的预算?(Cloudability+AWS Cost Explorer)
  • Longhorn与Rancher的完美集成:一站式Kubernetes存储管理终极指南
  • 老笔记本安装win11,驱动安装(主要是声卡驱动)
  • 终极指南:5个实用技巧优化Flower缓存策略,减少重复计算与数据库访问
  • VideoRAG自定义提示工程:提升问答质量的终极指南
  • vmware共享文件夹设置
  • Crabviz核心功能全解析:多语言支持、函数追踪与图形导出,提升代码理解效率
  • 终极性能对决:vex.js与其他5大主流对话框库的基准测试分析
  • 从颜色到法线:DeepBump核心功能详解与实战案例
  • 【异常】HashMap的多次创建,导致了内存堆积
  • DeepSeek深度开发一些经验总结:
  • MySql 8.0版本使用select group by报错的解决方案
  • 大数据-241 离线数仓 - 实战:电商核心交易数据模型与 MySQL 源表设计(订单/商品/品类/店铺/支付)
  • 解决Component组件化框架的10个常见问题:新手必备解决方案
  • 怎样下载安装使用nvm,并安装node和npm
  • Atom Package Manager深度解析:核心功能与架构原理
  • Mockery包管理终极指南:InPackage vs KeepTree模式深度对比
  • OS6.【Linux】基本指令入门(5)
  • 探索Win-SSHFS安全机制:如何保护你的远程文件传输
  • dockerfiles项目贡献指南:如何提交PR分享你的Dockerfile文件
  • 7分钟掌握Git快速统计工具:从安装到高级分析的完整指南