React-Router 一站式攻略:从入门到精通,掌握路由搭建与权限管控

文章目录

    • 一、前言
    • 二、安装
      • 使用 npm 安装(推荐)
      • 使用 yarn 安装
    • 三、基础使用
      • 设置路由基础结构
      • 定义路由和组件关联
        • 直接在组件中定义路由
        • 定义单独一个路由表
      • 创建导航链接
    • 四、核心组件和功能
      • BrowserRouter 和 HashRouter
      • Route 组件
      • Link 组件
      • Switch 组件
    • 五、路由参数和嵌套路由
      • 路由参数
      • 嵌套路由
      • 嵌套路由层级加深及应用场景拓展
    • 六、编程式导航
    • 七、路由权限
      • 路由表
      • 权限组件
      • 404 页面

一、前言

react-router 库在 React 应用开发中扮演着至关重要的角色,它是实现页面路由管理的核心工具,能够让开发者根据不同的 URL 路径精准地渲染对应的组件,这对于构建流畅、交互性强的单页面应用(SPA)来说不可或缺。通过它,用户在浏览应用时无需频繁刷新整个页面,就能实现页面内容的动态切换,极大地提升了用户体验。
例如,许多知名的 React 应用,如一些大型的电商平台前端、在线办公软件等,都借助 react-router 来管理繁多的页面路由,实现复杂的功能模块切换和页面导航,使得用户可以方便快捷地在各个功能页面之间穿梭。

一般来说,React-Router v6 需要 React v16.8 或更高版本。因为 React-Router v6 利用了 React 的 Hooks 等特性,而 React v16.8 是第一个引入 Hooks 的版本。如果使用较低版本的 React,可能会导致 React-Router 无法正常工作或某些功能缺失。

二、安装

使用 npm 安装(推荐)

  1. 打开终端,进入 React 项目目录。
  2. 若没安装 React 项目,可用 Create React App 等创建新项目。
  3. 在项目目录下,运行 npm install react-router-dom 命令,安装成功后,可查看 node_modules 目录有无 react-router-dom 文件夹,或在代码文件导入相关模块(如 import { BrowserRouter } from'react-router-dom')验证,无报错即安装正确。

使用 yarn 安装

  1. 打开终端,进入 React 项目目录。
  2. 运行 yarn add react-router-dom 命令,完成后即可使用。

三、基础使用

项目 React 版本: 18.3.1;react-router-dom 版本:7.1.1。

设置路由基础结构

在 React 应用入口文件(通常是 index.jsmain.js),用 BrowserRouter(基于浏览器历史记录,URL 更自然)或 HashRouter(特殊部署需求或兼容旧浏览器)包裹整个应用。如在 main.js 中:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App.jsx';createRoot(document.getElementById('root')).render(<StrictMode><Router><App /></Router></StrictMode>
);

这里将 App 组件包裹在 RouterBrowserRouter 的别名)中,这样 App 组件及其子组件就可以访问到路由相关的功能。

定义路由和组件关联

App 组件或其他组件内,用 Route 组件定义路由规则。

直接在组件中定义路由

这种方式将路由定义直接放在组件内部,对于小型应用或者路由规则比较简单的情况,具有直观的优点。开发者可以一目了然地看到某个组件与具体路由路径的关联情况,并且路由规则与组件紧密结合,很适合组件自身内部的路由管理,尤其当组件是独立的功能模块时,能使模块功能更加内聚。

import React from 'react';
import { Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
const App = () => {return (<div>{/* Route 组件定义路由,exact 精确匹配,确保路径完全是'/'才渲染 Home 组件,访问'/about'时不会渲染 Home 组件。访问'/'渲染 Home 组件,访问'/about'渲染 About 组件。*/}<Route exact path="/" component={Home} /><Route path="/about" component={About} /></div>);
}
export default App

然而,当应用规模逐渐变大,路由规则变得复杂时,这种写法会暴露出明显的缺点。比如在一个大型电商应用中,若有上百个路由都写在 App 组件内,代码会变得极为臃肿,查找特定路由关联的组件、修改路由参数等维护操作将变得异常繁琐,代码的可读性也会大打折扣,不利于后续的开发和维护。

定义单独一个路由表

单独创建一个路由表可以将所有的路由规则集中管理,这对于大型应用开发来说尤为重要。在开发过程中,开发者能够在一个文件中清晰地查看所有的路由路径、对应的组件以及可能的路由参数等关键信息。而且,路由表具备良好的复用性,比如在不同的布局组件(如具有不同侧边栏的布局)中,都可以引用这个统一的路由表来实现相同的路由功能,无需重复配置。同时,当需要对路由规则进行修改时,只需在路由表文件中操作即可,无需逐个在使用路由的组件中进行修改,极大地提高了开发效率和代码的可维护性。随着应用的不断发展,添加新路由也十分方便,并且对于路由的中间件(如权限验证,只有登录用户才能访问某些路由)等功能,在路由表中也能更便捷地进行配置。
创建 routes.js 文件定义路由表,集中管理路由规则。

import { lazy } from 'react';
// lazy 用于设置路由懒加载
const Home = lazy(() => import('@/pages/Home'));
const About = lazy(() => import('@/pages/About'));const Router = [{path: '/',element: <Home />},{path: '/about',element: <About />},// 设置 404 页面{path: '*',element: <NotFound />}
];export default Router

然后在 App 组件中使用这个路由表:

import router from './router';
import { Suspense } from 'react';
import { useRoutes } from 'react-router-dom';function App() {// useRoutes 依传入路由配置生成相应路由元素,代表应渲染组件树结构。const element = useRoutes(router);// Suspense 设页面跳转加载提示,组件加载时显示 fallback 指定内容。return <Suspense fallback={'loading...'}>{element}</Suspense>;
}export default App

此方式适用于大型应用,复用性好,修改路由便捷,还方便配置中间件(如权限验证)。

创建导航链接

使用 Link 组件来创建应用内部的导航链接,它与传统的 标签不同,当用户点击 Link 组件时,不会引起整个页面的刷新,而是通过 JavaScript 更新 URL 并触发相应的组件渲染,实现单页面应用内的无缝导航。

import React from 'react';
import { Link } from 'react-router-dom';const Navigation = () => {return (<nav>{/* Link 组件 to 属性指定导航目标路径,点击'Home'链接导航到根路径渲染 Home 组件,点击'About'链接导航到'/about'路径渲染 About 组件。*/}<Link to="/">Home</Link><Link to="/about">About</Link></nav>);
}export default Navigation

四、核心组件和功能

BrowserRouter 和 HashRouter

  • BrowserRouter:基于 HTML5 浏览器历史记录 API,URL 格式自然,无“#”符号,如电商产品详情页 URL 可为“/products/123”,利于 SEO。
  • HashRouter:用 URL 哈希部分管理路由,适用于旧浏览器或服务器不支持 HTML5 历史记录 API 的情况,部署在简单静态服务器上表现良好。

hash和history

Route 组件

Route 组件是核心,定义路由规则,关联 URL 路径与组件。

import React from 'react';
import { Route, BrowserRouter as Router } from 'react-router-dom';
import Home from './Home';
import About from './About';
const App = () => {return (<Router><Route exact path="/" component={Home} /><Route path="/about" component={About} /></Router>);
}
export default App

exact 属性精确匹配路径,避免误渲染。

Link 组件

与传统 <a> 标签不同,点击不刷新页面,更新 URL 触发组件渲染。

import React from 'react';
import { Link } from 'react-router-dom';
const Navigation = () => {return (<nav><Link to="/">Home</Link><Link to="/about">About</Link></nav>);
}
export default Navigation

Switch 组件

包裹一组 Route 组件,只渲染第一个匹配成功的 Route,防止多个组件同时渲染。

import React from 'react';
import { Route, Switch, BrowserRouter as Router } from 'react-router-dom';
import Home from './Home';
import About from './About';
import NotFound from './NotFound';
const App = () => {return (<Router><Switch><Route exact path="/" component={Home} /><Route path="/about" component={About} /><Route component={NotFound} /></Switch></Router>);
}
export default App

在这个例子中,如果没有Switch组件,当用户访问一个不存在的路径时,NotFound组件和前面可能部分匹配的组件(比如Home组件)都可能会被渲染。有了Switch组件,只有NotFound组件会被渲染,因为前面的路由都没有匹配成功

五、路由参数和嵌套路由

路由参数

React-Router 允许在路由路径中定义参数。例如,在一个列表中,内容详情页的路由可以定义为 /articles/:id,其中 :id 是一个参数,表示详情的唯一标识符。在组件中可以通过 props.match.params 获取这个参数。

import React from 'react';
import { Route, BrowserRouter as Router } from 'react-router-dom';
const ArticleDetail = props => {const articleId = props.match.params.id;// 根据 articleId 获取文章详情并渲染return (<div><h1>Article Detail {articleId}</h1></div>);
}
const App = () => {return (<Router><Route path="/articles/:id" component={ArticleDetail} /></Router>);
}
export default App

用户访问 /articles/123 时,articleId 为“123”。

嵌套路由

复杂应用有嵌套路由情况,如电商产品详情页有评论区。

import React from 'react';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';
import ProductDetail from './ProductDetail';
import ProductReviews from './ProductReviews';
const App = () => {return (<Router><Switch><Route path="/products/:id" component={ProductDetail}><Route path="/products/:id/reviews" component={ProductReviews} /></Route></Switch></Router>);
}
export default App

访问“/products/123/reviews”时,先渲染 ProductDetail 组件,再在其内部合适位置渲染 ProductReviews 组件。

嵌套路由层级加深及应用场景拓展

以企业级应用为例,展示部门详情页、员工列表页、员工个人详情页和员工绩效页等多层嵌套路由场景,通过合理配置实现页面有序切换。

import React from 'react';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';const DepartmentDetail = props => {return (<div><h1>Department Detail</h1>{/* 展示部门相关信息 */}<Route path={`${props.match.path}/employees`} component={EmployeeList} /></div>);
}const EmployeeList = props => {return (<div><h2>Employee List</h </div>{/* 展示员工列表 */}<Route path={`${props.match.path}/:employeeId`} component={EmployeeDetail} /><Route path={`${props.match.path}/:employeeId/performance`} component={EmployeePerformance} /></div>);
}const EmployeeDetail = props => {const { employeeId } = props.match.params;return (<div><h3>Employee Detail - ID: {employeeId}</h3>{/* 展示员工个人详细信息 */}</div>);
}const EmployeePerformance = props => {const { employeeId } = props.match.params;return (<div><h3>Employee Performance - ID: {employeeId}</h3>{/* 展示员工绩效相关信息 */}</div>);
}const App = () => {return (<Router><Switch><Route path="/departments/:departmentId" component={DepartmentDetail} /></Switch></Router>);
}export default App

通过这样的复杂示例,可以更好理解嵌套路由在构建大型、功能丰富的应用中是如何发挥作用的,以及如何根据实际业务需求去设计和配置多层嵌套的路由结构,更好地应对复杂的页面关系和功能模块划分

六、编程式导航

Link 组件,React-Router 支持编程式导航,通过 history 对象实现,可在组件中用 props.history 获取(组件需通过 Route 组件渲染)。

import React from 'react';
import { Route, BrowserRouter as Router, useNavigate } from 'react-router-dom';
const MyComponent = props => {const Navigate = useNavigate();const handleClick = () => {Navigate('/about');}return (<div><button onClick={handleClick}>Go to About</button></div>);
}
const App = () => {return (<Router><Route path="/" component={MyComponent} /></Router>);
}
export default App

点击按钮,调用 handleClick 函数,导航到“/about”路径,适用于表单提交成功等内部逻辑导航。

七、路由权限

路由表

import { lazy } from 'react';
import Auth from './AuthRoute';
const Home = lazy(() => import('@/pages/Home'));
const About = lazy(() => import('@/pages/About'));
const List = lazy(() => import('@/pages/List'));
const User = lazy(() => import('@/pages/User'));
const NotFound = lazy(() => import('@/pages/NotFound'));const Router = [{path: '/',element: <Home />},{path: '/about',element: <About />},{path: '/app/',element: (// 自定义权限组件<Auth><BasicLayout /></Auth>),errorElement: <NotFound></NotFound>,children: [{path: 'list',element: <List />},{path: 'list/user',element: <User />}]},// 设置404页面{path: '*',element: <NotFound />}
];export default Router

权限组件

import { useEffect, useRef } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { message } from 'antd';
import useUpdateEffect from '@/components/useUpdateEffect';export default function Auth({ children }: any) {const location = useLocation().pathname;const didMountRef = useRef(false);const Navigate = useNavigate();const token = localStorage.getItem('token');useEffect(() => {if (didMountRef.current) {if (!token) {message.error('您未登录,将跳转');setTimeout(() => {Navigate('/login');}, 1000);}} else {didMountRef.current = true;}}, [token]);return children;
}

404 页面

import React from 'react';const CommonLine = props => (// 根据个人需求改动<div>未找到该页面</div>
);
export default CommonLine

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501606.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux终端输入删除键backspace显示^H,输入上下左右键显示^A^B^C^D原理以及详细解决办法!

当我们装完Linux系统之后,我们可能会碰到按下删除键后出现^H这种情况。 同样,输入上下左右键显示^A^B^C^D这种情况。 这是为什么呢? 别急,后面我会说具体解决办法,先来看看这是为什么? 一、终端程序架构 首先,我们需要了解终端程序架构。 终端程序架构分为三层,分别…

ESP32 I2S音频总线学习笔记(一):初识I2S通信与配置基础

文章目录 简介为什么需要I2S&#xff1f;关于音频信号采样率分辨率音频声道 怎样使用I2S传输音频&#xff1f;位时钟BCLK字时钟WS串行数据SD I2S传输模型I2S通信格式I2S格式左对齐格式右对齐格式 i2s基本配置i2s 底层API加载I2S驱动设置I2S使用的引脚I2S读取数据I2S发送数据卸载…

JAVA:利用 Redis 实现每周热评的技术指南

1、简述 在现代应用中&#xff0c;尤其是社交媒体和内容平台&#xff0c;展示热门评论是常见的功能。我们可以通过 Redis 的高性能和丰富的数据结构&#xff0c;轻松实现每周热评功能。本文将详细介绍如何利用 Redis 实现每周热评&#xff0c;并列出完整的实现代码。 2、需求分…

vscode代码AI插件Continue 安装与使用

“Continue” 是一款强大的插件&#xff0c;它主要用于在开发过程中提供智能的代码延续功能。例如&#xff0c;当你在编写代码并且需要进行下一步操作或者完成一个代码块时&#xff0c;它能够根据代码的上下文、语法规则以及相关的库和框架知识&#xff0c;为你提供可能的代码续…

kafka开机自启失败问题处理

前言&#xff1a;在当今大数据处理领域&#xff0c;Kafka 作为一款高性能、分布式的消息队列系统&#xff0c;发挥着举足轻重的作用。无论是海量数据的实时传输&#xff0c;还是复杂系统间的解耦通信&#xff0c;Kafka 都能轻松应对。然而&#xff0c;在实际部署和运维 Kafka 的…

Linux Red Hat 7.9 Server安装GitLab

1、关闭防火墙 执行 systemctl disable firewalld 查看服务器状态 systemctl status firewalld 2、禁用selinux vi /etc/selinux/config 将SELINUX 的值改为 disabled 3、安装policycoreutils-python 执行 yum install policycoreutils-python 4、下载gitlab wget --co…

PostgreSQL对称between比较运算

本文介绍PostgreSQL对称between比较功能&#xff1a;between symmetric&#xff0c;在动态拼接SQL时利用它可以简化判断。PostgreSQL 9.4 及以上版本支持BETWEEN SYMMETRIC操作符&#xff0c;MySQL、Oracle、MsSQL没有对应功能。 between 比较 PostgreSQL的between结构允许你对…

[CTF/网络安全] 攻防世界 simple_php 解题详析

题目描述&#xff1a;小宁听说php是最好的语言,于是她简单学习之后写了几行php代码。 代码解读 $a$_GET[a]; 从HTTP GET请求参数中获取一个名为a的变量&#xff0c;并将其赋值给变量a。符号用于禁止错误输出&#xff0c;如果不存在参数a则会将变量a设置为NULL。 $b$_GET[b];…

日志聚类算法 Drain 的实践与改良

在现实场景中&#xff0c;业务程序输出的日志往往规模庞大并且类型纷繁复杂。我们在查询和查看这些日志时&#xff0c;平铺的日志列表会让我们目不暇接&#xff0c;难以快速聚焦找到重要的日志条目。 在观测云中&#xff0c;我们在日志页面提供了聚类分析功能&#xff0c;可以…

RabbitMQ基础篇之Java客户端快速入门

文章目录 需求 项目设置与依赖管理 配置RabbitMQ的连接信息创建队列与消息发送创建消费者&#xff08;消息接收&#xff09;环境准备与操作 需求 利用控制台创建队列 simple.queue在 publisher 服务中&#xff0c;利用 SpringAMQP 直接向 simple.queue 发送消息在 consumer 服…

在虚幻引擎4(UE4)中使用蓝图的详细教程

在虚幻引擎4&#xff08;UE4&#xff09;中使用蓝图的详细教程 虚幻引擎4&#xff08;Unreal Engine 4&#xff0c;简称UE4&#xff09;是一款功能强大的游戏引擎&#xff0c;广泛应用于游戏开发、虚拟现实、建筑可视化等领域。UE4 提供了一个强大的可视化脚本工具——蓝图&am…

初学STM32 ---高级定时器互补输出带死区控制

互补输出&#xff0c;还带死区控制&#xff0c;什么意思&#xff1f; 带死区控制的互补输出应用之H桥 捕获/比较通道的输出部分&#xff08;通道1至3&#xff09; 死区时间计算 举个栗子&#xff08;F1为例&#xff09;&#xff1a;DTG[7:0]250&#xff0c;250即二进制&#x…

MarkDown怎么转pdf;Mark Text怎么使用;

MarkDown怎么转pdf 目录 MarkDown怎么转pdf先用CSDN进行编辑,能双向看版式;标题最后直接导出pdfMark Text怎么使用一、界面介绍二、基本操作三、视图模式四、其他功能先用CSDN进行编辑,能双向看版式; 标题最后直接导出pdf Mark Text怎么使用 Mark Text是一款简洁的开源Mar…

华为ensp-BGP路由过滤

学习新思想&#xff0c;争做新青年&#xff0c;今天学习的是BGP路由过滤 实验目的&#xff1a; 掌握利用BGP路由属性AS_Path进行路由过滤的方法 掌握利用BGP路由属性Community进行路由过滤的方法 掌握利用BGP路由属性Next_Hop进行路由过滤的方法 实验内容&#xff1a; 本实…

HackMyVM-Airbind靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 使用ipv6绕过iptables 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(192.168.101.127) 靶 机&#xff1a;debian(192.168.101.11…

springcloud篇3-docker需熟练掌握的知识点

docker的原理请参考博文《Docker与Kubernetes》。 一、安装docker的指令 1.1 安装yum工具 yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken补充&#xff1a;配置镜像源 注意&#xff1a; yum安装是在线联网下载安装&#xff0c;而很多的资源…

ES IK分词器插件

前言 ES中默认了许多分词器&#xff0c;但是对中文的支持并不友好,IK分词器是一个专门为中文文本设计的分词工具&#xff0c;它不是ES的内置组件&#xff0c;而是一个需要单独安装和配置的插件。 Ik分词器的下载安装&#xff08;Winows 版本&#xff09; 下载地址&#xff1a;…

BP神经网络的反向传播算法

BP神经网络&#xff08;Backpropagation Neural Network&#xff09;是一种常用的多层前馈神经网络&#xff0c;通过反向传播算法进行训练。反向传播算法的核心思想是通过计算损失函数对每个权重的偏导数&#xff0c;从而调整权重&#xff0c;使得网络的预测输出与真实输出之间…

在Linux下安装部署Tomcat教程

摘要 Tomcat是由Apache开发的要给Servlet容器,实现了对Servlet 和JSP的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台,安全管理和Tomcat阀等。简单来说,Tomcat是一个由WEB应用程序的托管平台,可以让用户编写的WEB应用程序,别Tomcat所托管,并提供网…

vue学习第一阶段

vue 什么是Vue? 概念:Vue是一个构建用户页面的渐进式框架 Vue的两种使用方式 Vue的核心开发 场景: 局部 {\color{red}局部} 局部模块改造Vue核心包& Vue插件 工程化开发场景: 整站 {\color{red}整站} 整站开发Vue2官网 https://v2.cn.vuejs.org/ 资料存放地址 D:\Baidu…