React-Router

news2024/9/22 23:24:59

版本5

安装:

npm

npm install react-router-dom@5 -S

yarn

yarn add react-router-dom@5
import ReactDOM from "react-dom/client";

// react router适用于web和原生项目,我们在web项目中使用,所以需要引入的包是react-router-dom
import {BrowserRouter, Link, Route, Switch} from "react-router-dom";


const Home = () => {
    return <div>这是首页</div>;
};

const About = () => {
    return <div>关于</div>
};


const App = () => {
    return <div>
        <ul>
            <li>
                <Link to="/home">首页</Link>
            </li>
            <li>
                <Link to="/about">关于</Link>
            </li>
        </ul>
        <Switch>
            <Route path="/home" component={Home} />
            <Route path="/about" component={About} />
        </Switch>
    </div>;
};


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <BrowserRouter>
        <App/>
    </BrowserRouter>
);

Route组件

通过该组件将url地址和React组件进行映射,映射后当url地址变为指定地址时指定的组件就会显示,否则不显示。

<Route path="/home" component={Home} />
<Route path="/about" component={About} />

Route组件可以设置以下几个属性

  1. path

用来设置要映射的路径,可以是一个字符串或字符串数组。字符串用来匹配单个路径,数组可以匹配多个路径。看一个数组的例子:

<Route path={["/about", "/hello"]}>
    <About/>
</Route>

使用数组映射后,当我们访问数组中的路径时都会使组件挂载。设置路径时也可以在路径中设置参数,比如:/student/:id其中id就是一个参数,可以动态的传递:id的值,换句话说/student/1/student/2,都会触发组件挂载。

设置动态参数后,在组件的内部可以使用useParams()钩子来读取参数:

const Student = () => {
    const {id} = useParams();
    return <div>学生id:{id}</div>
};

<Route path="/student/:id">
    <Student/>
</Route>
  1. exact

路由的匹配默认并不是完整匹配,这意味着路由映射的地址是/home时,只要我们访问的路径是以/home开头就会触发组件的挂载,默认情况下是不会检查路由的子路径的。比如:/home/hello/home/abc等都会导致home组件挂载。

exact属性用来设置路由地址是否完整匹配,它需要一个布尔值,默认为false,就像上边的情况。如果设置为true,那么只有地址和path完全一致时,组件才会挂载。

<Route path="/home" exact>
    <Home/>
</Route>

这样一来只有访问/home时,home组件才会挂载,差一个字母都不行哦!

  1. strict

布尔值,默认值为false。false时,会匹配到以/结尾的路径。比如:path设置为/home默认情况下/home/也会导致组件挂载。设置为true时,以/结尾的路径不会被匹配。

  1. component

设置路径匹配后需要挂载的组件。作用和Route的标签体类似。

<Route path="/home" component={Home}/>

和标签体指定组件不同,如果通过component属性指定组件,React Router会自动向组件中传递三个参数match、location和history。

  • match

对象,表示请求匹配的路径信息,其中包含四个属性:

  1. param —— 请求参数

  1. isExact —— 布尔值,请求路径是否完整匹配

  1. path —— 请求路径的规则

  1. url —— 匹配到的url地址

  • location

对象,表示浏览器地址栏的信息,请求完整路径、查询字符串等,可能具有的属性:

  1. pathname —— 请求的路径

  1. search —— 查询字符串

  1. hash —— hash字符串

  1. state —— 历史记录中的状态对象,可以用来在跳转时传递数据

  • history

对象,用来读取和操作浏览器的历史记录(页面跳转)等功能,属性:

  1. length —— 历史记录的数量

  1. action —— 当前历史记录的状态,pop(前进、后退、新记录创建、索引发生变化);push(新记录添加);replace(历史记录被替换)

  1. location —— location对象

  1. push() —— 添加新的历史记录

  1. replace() —— 替换历史记录

  1. go() —— 跳转到指定记录

  1. goBack() —— 回退

  1. goForward() —— 前进

  1. block() —— 用来阻止用户跳转行为,可以用Prompt组件代替

About.js

import React from "react";

const About = (props) => {
  const clickHandler = () => {
    props.history.replace({
      pathname: "/student/2",
      state: { name: "哈哈" },
    });
  };
  return (
    <div>
      <button onClick={clickHandler}>点击</button>
    </div>
  );
};

export default About;

Student.js

import React from 'react';

const STU_DATA = [
    {
        id:1,
        name:'孙悟空'
    },
    {
        id:2,
        name:'猪八戒'
    },
    {
        id:3,
        name:'沙和尚'
    },
    {
        id:4,
        name:'唐僧'
    },
];

const Student = (props) => {
    const stu = STU_DATA.find(item => item.id === +props.match.params.id);
    return (
        <div>
            {stu.id} --- {stu.name}
        </div>
    );
};

export default Student;

App.js

import {Route} from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Menu from "./components/Menu";
import Student from "./components/Student";

function App() {
    return (
        <div className="App">
            <Menu/>

            {/*
                component用来指定路由匹配后被挂载的组件
                    component需要直接传递组件的类
                    通过component构建的组件,它会自动创建组件并且会自动传递参数
                        match -- 匹配的信息
                            isExact 检查路径是否完全匹配
                            params 请求的参数
                        location -- 地址信息
                        history -- 控制页面的跳转
                            push() 跳转页面
                            replace() 替换页面
            */}
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
            {/*
                /student/:id 会匹配到 /student/xxx
            */}
            <Route path="/student/:id" component={Student}/>
        </div>

    );
}

export default App;

5.render

render也是Route组件中的属性,和component类似,也用来指定路径匹配后需要挂载的组件。只是render需要的是一个回调函数作为参数,组件挂载时,render对应的回调函数会被调用,且函数的返回值会成为被挂载的组件。render的回调函数中会接收到一个对象作为参数,对象中包含三个属性,即match、location和history,我们可以根据需要选择是否将其传递给组件。

<Route path="/student/:id" render={routeProps => <Student {...routeProps}/>} />
routeProps 就是 historys location match

const Student = (props) => {

    console.log(props);
    const stu = STU_DATA.find(item => item.id === +props.match.params.id);
    return (
        <div>
            {stu.id} --- {stu.name}
        </div>
    );
};

6.children

children实际上就是组件的组件体,设置方式有两种一个是通过组件体设置,一个是通过children属性设置。它的值也有两种方式,一种直接传递组件,这样当路径匹配时组件会自动挂载。一种是传递一个回调函数,这样它和render的特点是一样的。

直接设置组件:

<Route path="/student/:id" children={<Student/>} />
<Route path="/student/:id">
    <Student/>
</Route>

传递回调函数:

<Route path="/student/:id" children={routeProps => <Student {...routeProps}/>} />
<Route path="/student/:id">
    {routeProps => <Student {...routeProps}/>}
</Route>

需要注意的时,当children接收到的是一个回调函数时,即使路径没有匹配组件也会被挂载到页面中(没有使用Switch标签的情况下),这一特性可以在一些特殊应用场景下发挥作用。如果不希望出现路径不匹配时组件被挂载的情况,最好选择使用render来代替。

Switch组件

Switch组件是Route组件的外部容器,可以将Route组件放入到Switch组件中。放入Switch组件中后,匹配路径时会自动自上向下对Route进行匹配,如果匹配到则挂载组件,并且一个Switch中只会有一个Route被挂载。如果将Route组件单独使用,那么所有的路径匹配的Route中的组件都会被挂载。

Link组件

Link组件作用类似于a标签(超链接),并且Link组件在浏览器中也会被渲染为超链接。但是Link组件生成的链接点击后只会修改浏览器地址栏的url,并不会真的向服务器发送请求。这种方式有利于组件的渲染,所以在开发中应该使用Link组件而不是超链接。

HashRouter组件

除了BrowserRouter以外,react router中还为我们提供了HashRouter,它是干什么用的呢?其实很简单,当我们使用BrowserRouter时,路径会直接根据url地址进行跳转,也就是我们在使用应用时在浏览器的地址栏看到的地址就和我们正常去访问网页一样。

但是,HashRouter不是这样,使用HashRouter时,组件的跳转不再是以完整的url形式,而是通过url地址中的hash值进行跳转(url地址中#后的内容为hash值)。

BrowserRouter的地址栏

HashRouter的地址栏

为什么会有这两种Router呢?首先,你要明确我们的项目在开发完成后需要进行构建,构建后的代码需要放到服务器中,以供用户访问。服务器无非就是Nginx或Apache这些东西,服务器的主要功能是将url地址和网页进行映射。传统web项目中,每一个页面都对应一个文件,当用户访问/index.html时,服务器会自动返回根目录下的index.html。当用户访问/about.html时,服务器会返回根目录下about.html。换句话说url和文件的映射都是由服务器来完成的。

但是React项目不同,React项目所有的页面都是通过React进行渲染构建的。项目中只存在一个index.html没有那么多的页面(所以才叫单页应用)。当浏览器地址发生变化时,比如用户访问/about时,此时是不需要服务器介入的,react router会自动挂载对应的组件。

当我们将React项目部署到服务器时,如果直接访问根目录,请求会直接发送给index.html。这个页面我们是有的,所以此时不会有任何问题。用户访问页面后,点击页面后的连接切换到不同的组件也没有问题,因为页面并没有真的发生跳转,而是通过react router在内存中完成了模拟跳转。但是,当我们刷新某个路由或直接通过浏览器地址栏访问某个路由时,比如:http://localhost:3000/about,此时请求会发送给服务器,服务器会寻找名为about的资源(此时并没有经过React)。显然找不到这个资源,于是返回404。

这样一来,我们的项目只能够通过首页访问,然后点击链接跳转,刷新和直接通过路由访问都是不行的,一旦进行这些操作就会出现404。

怎么办呢?两种解决方式:

  1. 使用HashRouter,HashRouter通过hash地址跳转,而服务器不会处理hash地址,这样地址就会交由React处理,路由便可正常跳转。缺点是url地址上总会多出一个#,但不妨碍使用。

  1. 修改服务器映射规则,将所有的请求交给React处理,禁止服务器自动匹配页面。以nginx为例,可以将nginx.conf中的配置信息修改如下:

location / {
    root   html;
    try_files $uri /index.html;
}

两种方式都可以解决404的问题,具体采用那种方案,需要根据你自己项目的实际情况选择。

NavLink组件

特殊版本的Link,可以根据不同的情况设置不同的样式。

属性:

  1. activeClassName —— 字符串 链接激活时的class

  1. activeStyle —— 对象 链接激活时的样式

  1. isActive —— 函数,可动态判断链接是否激活

  1. style —— 函数,动态设置样式

  1. className —— 函数,动态设置class值

Redirect组件

将请求重定向到一个新的位置,经常用来进行权限的处理。例如:当用户已经登录时则正常显示组件,用户没有登录时则跳转到登录页面。

{isLogin && <SomeAuthComponent/>}
{!isLogin && <Redirect to={"/login"}></Redirect>}

上例中,如果isLogin的值为true,表示用户已经登录,若用户登录,则挂载对应组件。若isLogin值为false,则挂载Redirect组件触发重定向,重定向会使得路径跳转到登录页面。

属性:

  1. to —— 重定向的目标地址,可以是一个字符串也可以是一个对象

  1. from —— 需要重定向的地址

  1. push —— 布尔值,是否使用push方式对请求进行重定向

版本6

安装:

npm

npm install react-router-dom@6 -S

yarn

yarn add react-router-dom@6
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import { BrowserRouter as Router, Link, Route, Routes } from ‘react-router-dom’;

const Home = ()=>{
  return <div>首页</div>
};

const About = () => {
  return <div>关于</div>
};

const App = () => {
  return <div>App
    <ul>
      <li>
        <Link to=”/”>home</Link>
      </li>
      <li>
        <Link to=”/about”>about</Link>
      </li>
    </ul>

    <Routes>
      <Route path=”/” element={<Home/>}/>
      <Route path=”/about” element={<About/>}/>
    </Routes>
  </div>;
};

const root = ReactDOM.createRoot(document.getElementById(‘root’));

root.render(
  <Router>
    <App />
  </Router>
);

Route组件

Route作用和版本5的一样,只是变得更简单了,没有了那么多复杂的属性,并且Route组件必须放到Routes中,当浏览器的地址发生变化时,会自动对Routes中的所有Route进行匹配,匹配到的则显示,其余Route则不再继续匹配。可以将Route当成是一个类似于if语句的东西,路径(path)匹配则其中的组件便会被渲染。

  1. path —— 要匹配的路径

  1. element —— 路径匹配后挂载的组件,直接传JSX

  1. index —— 布尔值,路由是否作为默认组件显示

Outlet组件

Outlet组件用来在父级路由中挂载子路由。

在版本6中Route组件是可以嵌套的,可以通过嵌套Route来构建出嵌套路由,像这样:

<Route path='/students' element={<StudentList/>}>
    <Route path=':id' element={<Student/>}/>
</Route>

上例中,Route嵌套后,如果访问/students则会挂载StudentList组件,如果访问/students/:id则会自动在StudentList组件中对Student组件进行挂载。在StudentList组件中就可以使用Outlet来引用这些被挂载的组件。

const StudentList = () => {
    return <div>
        学生列表
        <Outlet/>
    </div>
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Idea 安装 Sonar 插件提升代码质量

目录 0. 环境说明 1. Sonar 简介 2. IDEA 配置 Sonar 0. 环境说明 Java 1.8IDEA 2022.3.1SonarLint 7.4.0 1. Sonar 简介 在多人协通的软件开发过程中&#xff0c;代码风格和代码质量对于软件的整体交付是十分关键的。这时我们可以利用 Sonar 插件&#xff0c;对代码进行扫描…

Spring MVC注解Controller源码流程解析--HandlerAdapter执行流程--上

Spring MVC注解Controller源码流程解析--HandlerAdapter执行流程--上引言RequestMappingHandlerAdapter方法参数解析器方法参数名解析器类型转换体系简单的使用演示数据绑定器工厂定制化修改DataBinder获取泛型参数ControllerAdvice与InitBinder注解控制器方法执行流程Controll…

C语言(可变参数:stdarg.h)

目录 一.使用可变参数 1.提供一个使用省略号的函数原型 2.在函数定义中创建一个va_list类型的变量 3.用宏把该变量初始化为一个参数列表 4.用宏访问参数列表 5.使用宏完成清理工作 二.va_copy 三.实例 一.使用可变参数 该头文件提供类似接受可变数量参数的宏&#xf…

【招聘】永善县正向社会工作服务中心招聘2名工作人员

永善县正向社会工作服务中心面向社会公开招聘2名工作人员 永善县正向社会工作服务中心是2019年9月在永善县民政局注册登记成立的民办非企业单位。业务范围主要为&#xff1a;面向社会提供各类专业社工服务&#xff0c;开展活动策划、个案援助等社会服务项目&#xff1b;承接个人…

基于WEB的小型公司人事管理系统设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着当代各类企业公司员工数量越来越多、分工越来越细化、各行各业之间的联系越发密切&#xff0c;对人事管理的要求也不断提高。实现企业人事管理计算机化&#xff0c;毫无疑问会让企业的人事管理变得更加高效化和智能化。企业要生…

c/c++开发,无可避免的函数参数实践

一、函数参数表 函数由函数名以及一组操作数类型唯一地表示。函数的操作数&#xff0c;也即形参&#xff0c;在一对圆括号中声明&#xff0c;形参与形参之间以逗号分隔。每一个函数都有一个相关联的返回类型。 int setval(int val) {//函数体 }; 这里&#xff0c;定义了一个名…

Vulkan教程(14): Graphics pipeline之Fixed functions(固定管线功能)

Vulkan官方英文原文&#xff1a;https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Fixed_functions对应的Vulkan技术规格说明书版本&#xff1a; Vulkan 1.3.2The older graphics APIs provided default state for most of the stages of the graphic…

个人如何获得免费的VMware Fusion Player?在macOS上虚拟化系统

不管是开发还是测试&#xff0c;有时候都需要虚拟机。比如虚拟化一台Linux&#xff0c;部署Web服务进行服务器仿真操作。亦或者&#xff0c;macOS上虚拟化Windows&#xff0c;进行Windows环境模拟。 VMware这家公司&#xff0c;大家应该都比较熟悉。旗下的VMware Workstation在…

LabVIEW NI网络设备在MAX中不显示或未识别

LabVIEW NI网络设备在MAX中不显示或未识别有一个NI设备通过网络连接到主机。发生以下情况之一&#xff1a;尝试在Measurement&#xff06;AutomationExplorer&#xff08;MAX&#xff09;中配置设备。设备未显示在“远程系统”下。NIMAX中未检测到CompactRIO&#xff08;cRIO&a…

2D图像处理:2D Shape_Base_Matching_缩放_旋转_ICP_显示ROI

文章目录 调试结果参考调试说明问题0:并行运行问题问题1:模板+Mask大小问题问题2:组合缩放和旋转问题3:可以直接将计算边缘的代码删除问题4:如何在原始图像上显示匹配到的ROI问题5:计算的原始旋转角度不需要判断,直接可以在ICP中使用问题6:绘制坐标轴问题7:绘制ROI调试…

图像优化篇

目录&#xff08;1&#xff09;矢量图&#xff08;2&#xff09;位图 2.1 分辨率2&#xff0c;图像格式格式选择建议&#xff1a;&#xff08;1&#xff09;矢量图 被定义为一个对象&#xff0c;包括颜色&#xff0c;大小&#xff0c;形状&#xff0c;以及屏幕位置等属性&…

Netty实现Http服务器案例

功能&#xff1a;Netty服务器在6668端口监听&#xff0c;浏览器发出请求"http://localhost:6668"服务器可以恢复消息给浏览器&#xff1a;“hello&#xff0c;我是服务器”&#xff0c;并对特定请求资源进行过滤目的&#xff1a;Netty可以做服务器端开发&#xff0c;…

家政服务小程序实战教程07-轮播图组件

小程序中首页一般显示轮播图的功能&#xff0c;点击轮播图会跳转到具体的一篇文章或者是产品&#xff0c;本篇我们就介绍一下轮播图功能的开发 01 设计数据源 我们轮播图组件需要两个字段&#xff0c;一个是展示的图片&#xff0c;一个是跳转页面传入的参数。打开数据源&…

JAVA集合专题5 ——ArrayDeque + BlockingQueue

目录ArrayDeque的特点BlockingQueue什么是BlockingQueue?什么叫阻塞队列?阻塞队列的应用场景是什么?BlockingQueue的阻塞方法是什么?BlockingQueue的四类方法codecode2ArrayDeque的特点 ArrayDeque是Deque接口子实现ArrayDeque数据结构可以表示为: 队列、双端队列、栈Arra…

【MFC】工具条(16)

创建工具条的基本步骤是&#xff1a; 1.创建工具条资源。 2.构建一个CToolBar对象。 3.调用CToolBar::Create函数创建工具条窗口。 4.调用CToolBar::LoadToolBar载入工具条资源。 使用工具条 打开资源视图&#xff0c;可视化创建或者修改工具条&#xff1a; 其中ID项一般与菜…

【计组】硬盘--《深入浅出计算机组成原理》(十二)

目录 一、机械硬盘 二、SSD硬盘 &#xff08;一&#xff09;SSD硬盘的读写原理 1、SLC、MLC、TLC 和 QLC 2、P/E 擦写问题 &#xff08;二&#xff09;SSD 读写的生命周期 &#xff08;三&#xff09;磨损均衡、TRIM 和写入放大效应 1、FTL 和磨损均衡 2、TRIM 指令的…

vueday01-脚手架安装详细

一、vue脚手架安装命令npm i -g vue/cli 或 yarn global add vue/cli安装上面的工具&#xff0c;安装后运行 vue --version &#xff0c;如果看到版本号&#xff0c;说明安装成功或 vue -V工具安装好之后&#xff0c;就可以安装带有webpack配置的vue项目了。创建项目之前&#…

用队列实现栈VS用栈实现队列

之前我们就讲过队列&#xff0c;栈的基础知识&#xff0c;笔者之前有过详细的介绍&#xff0c;感兴趣的可以根据笔者的个人主页进行查找&#xff1a;https://blog.csdn.net/weixin_64308540/?typelately225. 用队列实现栈请你仅使用两个队列实现一个后入先出&#xff08;LIFO&…

加入bing体验chatGPT大军中来吧,它来了!

1 第一步&#xff1a;加入候选名单 1、首先需要加入候选名单 https://www.microsoft.com/zh-cn/edge?formMA13FJ 2、下载最新的Edge浏览器、androd、iOS都有试用版本&#xff08;可以看到iOS加护当前已满&#xff09; 这里我下载的是dev版本&#xff0c;Canary版本由于是…

50. Pow(x, n)

50. Pow(x, n) 一、题目描述&#xff1a; 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即&#xff0c;xn &#xff09;。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;1024.00000 示例 2&#xff1a; 输入&#xff1a;x 2…