React-路由进阶

一、路由的使用

1.声明式导航

  • src/index.js文件中定义一个路由模式(可选,也可以在具体的某个组件中使用Router)

import React from "react";
import ReactDOM from "react-dom";// 设置路由模式
import {HashRouter as Router} from 'react-router-dom'// 定义 provider
import { Provider } from "react-redux";
import store from "./Store/index";import App from "./App";ReactDOM.render(<Provider store={store}>{/* 使用Router包裹根组件 */}<Router><App></App></Router></Provider>,document.getElementById("root")
);

 

  • 在根组件src/App.js中引入路由相关组件(根据自身需要选择路由模式),并使用

    • 后续除了特殊的路由规则(嵌套路由)以外,其它普通的路由规则都需要在根组件中运用

import React, { Component } from "react";
import { HashRouter as Router, Route, Link } from "react-router-dom";import Cmp10 from "./Components/Cmp10";
import Cmp11 from "./Components/Cmp11";class App extends Component {render() {return (<Router><div><h1>导航区域</h1><div><ul><li><Link to="/home">首页</Link></li><li><Link to="/news">新闻</Link></li></ul></div></div><Route path="/home" component={Cmp10}></Route><Route path="/news" component={Cmp11}></Route></Router>);}
}export default App;

在写上述代码时注意,路由自带组件的顺序嵌套关系,组件<Link></Link>和组件<Route></Route>必须被组件<Router></Router>给包裹着。

需要注意:

刨除样式的影响,Route组件在HTML代码中的位置决定了渲染后其在页面中显示的位置。如果Route放在最后,则其显示的时候也在最后;若其放在渲染内容的最前面,相应的显示也会在最开始。

2.编程式导航

react-router-dom中通过history对象中的push/go等方法实现编程式导航功能,这一点与之前的vue路由还是很相似的。

this.props.history.push({pathname: "/home",search: "from=404",	// 表示传递查询字符串state: {				// 隐式传参,地址栏不体现username: "admin",},
});// 给定给定的数字(正数或负数)决定去往历史栈中的哪个地址,正数往未来,负数往过去
this.props.history.go(-1)
this.props.history.goBack(-1)

请勿在根组件中写编程式导航,因为根组件默认是没有props对象,解决办法见后续。

 案例:
import React, { Component } from "react";
import { parseSearch } from "../utils/function";
export default class index extends Component {// 编程式导航render() {console.log(this.props);const { push } = this.props.history;// 接收query参数const { search } = this.props.location;// 获取路径中的参数转为对象格式 1. 使用new URL 拼接路径 + 需要转换的参数const urlObj = new URL("http://localhost" + search);// 2.使用Object.fromEntries 将urlObj.searchParams 转换 为一个新的对象console.log(Object.fromEntries(urlObj.searchParams));// 精简写法console.log(Object.fromEntries(new URL("http://localhost" + search).searchParams));// 封装写法console.log(parseSearch(search));return (<div>{/* <button onClick={() => push("/news")}>去新闻页</button> */}<buttononClick={() =>push({pathname: "/news",search: "id=100",state: { login: true },})}>去新闻页</button></div>);}
}

 

二、路由参数

路由参数:在Route定义渲染组件时给定动态绑定的参数。

React路由传参方式有三种:

  • ==动态路由参数(param)==

    • 以“/film/detail/:id”形式传递的数据

    • 在目标页面路由中传递

    • 在落地组件中通过this.props.match.params得到

    • 一般用于restful规范下的开发

  • 查询字符串(query)

    • 通过地址栏中的 ?key=value&key=value传递

    • 在落地组件中通过this.props.location.search得到

    • 由于得到的数据是带“?”的,还需要进一步加工处理之后才能使用,因此建议少用或者不用

  • 式传参(state),通过地址栏是观察不到的

    • 不合适写在声明式导航中,写在编程式导航中更加合适

    • 一般数用于埋点数据

      • 简单的讲,埋点是将部分标记隐藏起来,等待用户去触发,因为这个事情不想让用户看到(需要做一些数据的收集,后续做分析),因此会使用隐式传参的方式(大数据分析)

    • 在落地组件中通过this.props.location.state得到

接收示例:

constructor(props){super(props)this.state = {// 接收动态路由参数news_id: this.props.match.params.id,// 接收查询字符串并处理query: querystring.parse(this.props.location.search.slice(1)),// 接收statestate: this.props.location.state};
}
案例:

首页:

import React, { Component } from "react";
import { NavLink } from "react-router-dom";
import { Route } from "react-router-dom/cjs/react-router-dom.min";import index from "./pages/index";
import news from "./pages/news";
// 样式
import './assets/css/App.css'
export default class App extends Component {render() {return (<div><ul>{/* 声明式导航  标签式导航 */}<li>{/* 字符串传参 */}<NavLink to="/index?name=index">首页</NavLink></li><li>{/* 路径传参 */}<NavLink to="/news/100">新闻页</NavLink></li></ul><hr /><Route path="/index" component={index}></Route>{/* 在匹配params 动态参数时 需要设置传递名称  ?表示可传可不传*/}<Route path="/news/:id?" component={news}></Route></div>);}
}

index页面

import React, { Component } from "react";
import { parseSearch } from "../utils/function";
export default class index extends Component {// 编程式导航render() {console.log(this.props);const { push } = this.props.history;// 接收query参数const { search } = this.props.location;// 获取路径中的参数转为对象格式 1. 使用new URL 拼接路径 + 需要转换的参数const urlObj = new URL("http://localhost" + search);// 2.使用Object.fromEntries 将urlObj.searchParams 转换 为一个新的对象console.log(Object.fromEntries(urlObj.searchParams));// 精简写法console.log(Object.fromEntries(new URL("http://localhost" + search).searchParams));// 封装写法console.log(parseSearch(search));return (<div>{/* <button onClick={() => push("/news")}>去新闻页</button> */}<buttononClick={() =>push({pathname: "/news",search: "id=100",state: { login: true },})}>去新闻页</button></div>);}
}

news页面

import React, { Component } from "react";
class news extends Component {render() {// 获取params 参数console.log(this.props.match.params);// 获取state 参数console.log(this.props.location.state);return <div>news</div>;}
}export default news

三、重定向与404路由

1.重定向路由

React的重定向路由有以下写法:

在重定向的时候需要知道,从哪里来,到哪里去,因此该组件需要使用2个属性:

  • from:匹配需要重定向的路由

  • to:需要去往的路由

import { Redirect } from "react-router-dom"<Redirect from="/from" to="/to"></Redirect>

注意:

  • 建议使用Route书写路由规则时,使用Switch组件包裹Route组件,以便最多只能匹配一个规则

  • 建议给Redirect组件加上exact属性,来设置严格匹配模式

案例:

import React, { Component } from "react";
import { NavLink, Redirect,Switch } from "react-router-dom";
import { Route } from "react-router-dom/cjs/react-router-dom.min";import index from "./pages/index";
import news from "./pages/news";
// 样式
import "./assets/css/App.css";
export default class App extends Component {render() {return (<div><ul>{/* 声明式导航  标签式导航 */}<li>{/* 字符串传参 */}<NavLink to="/index?name=index">首页</NavLink></li><li>{/* 路径传参 */}<NavLink to="/news/100">新闻页</NavLink></li></ul><hr /><Switch>{/* 重定向 exact 严格匹配  配合switch 匹配一箱 */}<Redirect from="/" to="/index" exact></Redirect><Route path="/index" component={index}></Route>{/* 在匹配params 动态参数时 需要设置传递名称  ?表示可传可不传*/}<Route path="/news/:id?" component={news}></Route></Switch></div>);}
}

 2.404路由

项目中少不了404页面的配置,在React里面配置404页面需要注意:

  • 需要用到Switch组件,让其去包裹路由的Route组件(Switch组件保证只渲染其中一个子路由)

import NotFound from "./Components/404";<Route><NotFound></NotFound>
</Route>
// 或<Route component={NotFound}></Route>

注意:在404路由的位置,不需要给定具体的路由匹配规则,不给path表示匹配*,即所有的路由都会匹配,因此用404路由一定要加Switch匹配一个路由。

注意:并不会因为当前是404路由/重定向路由而改变状态码,因为当前写的是前端的内容,状态码是后端提供的,只有等后期上线以后才能有状态码。

案例:

import React, { Component } from "react";
import { NavLink,Switch } from "react-router-dom";
import { Route } from "react-router-dom/cjs/react-router-dom.min";import index from "./pages/index";
import news from "./pages/news";
import NotFound from "./components/NotFound";
// 样式
import "./assets/css/App.css";
export default class App extends Component {render() {return (<div><ul>{/* 声明式导航  标签式导航 */}<li>{/* 字符串传参 */}<NavLink to="/index?name=index">首页</NavLink></li><li>{/* 路径传参 */}<NavLink to="/news/100">新闻页</NavLink></li></ul><hr /><Switch><Route path="/index" component={index}></Route>{/* 在匹配params 动态参数时 需要设置传递名称  ?表示可传可不传*/}<Route path="/news/:id?" component={news}></Route>{/* 404路由必须加switch  在版本留替换为  Routes*/}<Route path="*" component={NotFound}></Route></Switch></div>);}
}

 404页面

import React, { Component } from "react";export default class NotFound extends Component {componentDidMount() {const {goBack} = this.props.history// 执行副作用setTimeout(() => {goBack()},3000)}render() {return <div>404 NotFound</div>;}
}

四、路由渲染方式和withRouter

v6中采用了新的属性对组件进行渲染,属性名:element

Route路由渲染组件是用于路由规则匹配成功后组件渲染容器,此组件提供了3种方式组件渲染方式:

  • component属性(组件对象/函数)

    • <Route path="/home" component={Home} />
    • <Route path="/home" component={(props) => <Home />} />
  • render属性(函数)

    • <Route path="/home" render={(props) => <Home />} />
  • children属性(组件/函数

    • <Route path="/about" children={(props) => {if(props.match){return <div>children渲染</div>}
      }} />
    • <Route path="/about" children={<About />} />

注意点

  • 当children的值是一个函数时,无论当前地址和path路径匹不匹配,都将会执行children对应的函数,当children的值为一个组件时,当前地址和path不匹配时,路由组件不渲染

  • children函数方式渲染,会在形参中接受到一个对象,对象中match属性如果当前地址匹配成功返回对象,否则null

withRouter

作用:把不是通过路由切换过来的组件中,将react-router 的 history、location、match 三个对象传入props对象上

默认情况下,必须是经过路由匹配渲染的组件才存在this.props,才拥有路由参数,才能使用编程式导航的写法,才能执行this.props.history.push('/uri')跳转到对应路由的页面。然而不是所有组件都直接与路由相连的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,此时就可以使用this.props。

// 引入withRouter
import { withRouter} from 'react-router-dom'
​
// 执行一下withRouter
export default withRouter(Cmp)

该高阶组件是路由包自带的东西,因此只需要引入+使用就可以了,不需要自己定义。

V5与V6的变化

  • Switch被废弃,由Routes替代,并且Routes是必须的

  • 渲染组件的方式被element属性替代,例如:

    • <Route path="/dashboard" element={<Dashboard />} />
  • 重定向组件Redirect被废弃,使用以下语法替代:

    • <Route path="/" element={<Navigate to="/dashboard/welcome" />} />
  • 嵌套路由被简化

    • 父路由:

      • <Route path="/dashboard/*" element={<Dashboard />} />
    • 子路由(子路由规则中不再需要写父前缀):

      • <Route path="welcome"  element={<Welcome/>}/>
  • 废弃了withRouter

 案例:

主页面

import React, { Component } from "react";
import { NavLink,Switch } from "react-router-dom";
import { Route } from "react-router-dom/cjs/react-router-dom.min";import index from "./pages/index";
import News from "./pages/news";
import NotFound from "./components/NotFound";
// 样式
import "./assets/css/App.css";
export default class App extends Component {render() {return (<div><ul>{/* 声明式导航  标签式导航 */}<li>{/* 字符串传参 */}<NavLink to="/index?name=index">首页</NavLink></li><li>{/* 路径传参 */}<NavLink to="/news/100">新闻页</NavLink></li></ul><hr /><Switch><Route path="/index" component={index}></Route>{/* 在匹配params 动态参数时 需要设置传递名称  ?表示可传可不传*/}{/* <Route path="/news/:id?" component={News}></Route> */}{/* 函数渲染方式  (不常用) 如果使用该方法传参 搭配 withRouter 包装使用*/}{/* <Route path="/news/:id?" component={(props)=><News/>}></Route> */}{/* render 函数渲染方式 (不常用) 如果使用该方法传参 搭配 withRouter 包装使用*/}{/* <Route path="/news/:id?" render={()=><News></News>}></Route> */}{/* children 函数渲染方式 (不常用) 如果使用该方法传参 搭配 withRouter 包装使用*/}<Route path="/news/:id?" children={<News/>}></Route>{/* children 组件渲染方式 (不常用) */}<Route path="/news/:id?" children={News}></Route>{/* 404路由必须加switch  在版本留替换为  Routes*/}<Route path="*" component={NotFound}></Route></Switch></div>);}
}

子页面

import React, { Component } from "react";// import { withRouter } from "react-router-dom";// class news extends Component {
//   render() {
//     // 获取params 参数
//     console.log(this.props.match.params);
//     // 获取state 参数
//     console.log(this.props.location.state);
//     return <div>news</div>;
//   }
// }// export default withRouter(news)class news extends Component {render() {// 获取params 参数console.log(this.props.match.params);// 获取state 参数console.log(this.props.location.state);return <div>news</div>;}
}export default news

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

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

相关文章

Python教程37:使用turtle画一个戴帽子的皮卡丘

---------------turtle源码集合--------------- Python教程36&#xff1a;海龟画图turtle写春联 Python源码35&#xff1a;海龟画图turtle画中国结 Python源码31&#xff1a;海龟画图turtle画七道彩虹 Python源码30&#xff1a;海龟画图turtle画紫色的小熊 Python源码29&a…

基于宝塔搭建Discuz!论坛

一、安装宝塔 我是在我的虚拟机上安装图的宝塔 虚拟机版本&#xff1a;Ubuntu 18.04 wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh 6dca892c安装完成之后在浏览器输入你的地址 https://你的域名&#xff08;或…

【Java的导入导出Excel操作详细介绍】

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

etcd集群搭建

etcd构建自身高可用集群主要有三种形式&#xff1a; 静态发现: 预先已知etcd集群中有哪些节点&#xff0c;在启动时通过--initial-cluster参数直接指定好etcd的各个节点地址etcd动态发现: 静态配置前提是在搭建集群之前已经提前知道各节点的信息&#xff0c;而实际应用中可能存…

抽奖小程序

import random import keyboard import timedef make_choice():while True:choice_selected random.choices([乾, 坤, 坎, 离, 兑, 震, 巽, 艮])[0]print(choice_selected, end\r)# time.sleep(0.1)if keyboard.is_pressed(enter):return choice_selectedif __name__ __main_…

基于JavaWeb+BS架构+SpringBoot+Vue校园一卡通系统的设计和实现

基于JavaWebBS架构SpringBootVue校园一卡通系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 第一章 概述 4 1.1 研究背景 4 1.2研究目的及意义 4 1.3国内外发展现状 4 1…

视觉SALM与激光SLAM的区别

前言&#xff1a; 这里比较一下视觉SLAM和激光SLAM的区别&#xff0c;仅比较其在算法层面上的一些不同&#xff0c;这里拿视觉SLAM算法&#xff1a;ORB-SLAM系列和激光SLAM算法&#xff1a;LOAM系列对比。 一&#xff1a;特征提取 1.ORB-SLAM&#xff08;视觉SLAM&#xff0…

什么是跨境电商独立站?

你是否有过这样的经历&#xff1a;当你在网上浏览一些商品时&#xff0c;发现有些网站的域名很奇怪&#xff0c;比如 .com、.net、.co等&#xff0c;而且网站的界面和设计也和国内的电商平台不太一样。 你可能会好奇&#xff0c;这些网站是什么&#xff1f;它们是怎么做的&…

网络安全之你的浏览器记录真的安全吗?

密码是每个人最私密的东西&#xff0c;轻易是不会展示给他人的&#xff0c;那么我如何能知道你电脑上浏览器里保存的密码呢&#xff1f;浏览器是大家在网上冲浪最常用的软件&#xff0c;在登录一些网站填写账号密码后&#xff0c;浏览器为了方便大家使用&#xff0c;会提示是否…

2.4G SOC无线收发芯片:XL2401D 产品介绍

XL2401D芯片是工作在2.400~2.483GHz世界通用ISM频段,集成微控制器的的SOC无线收发芯片。芯片集成射频收发机、频率收生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持对多组网和带 ACK的通信模式。发射输出功率、工作频道以及通信数据率均可配置。芯片内含以EPROM作…

unity小程序websocket:nginx配置https (wss)转http (ws)及其他问题解决

目录 前言 实际运用场景 处理流程如下 nginx配置ssl和wss 配置过程中遇到的问题 1、无法连接服务器 2、通过IP可以访问&#xff0c;域名却不行 问题描述 解决 3、如何判断该域名是否备案了 前言 为了服务器网络的通用性&#xff0c;我们在实现移动端的游戏转微信小程序…

Python教程38:使用turtle画动态粒子爱心+文字爱心

Turtle库是Python语言中的一个标准库&#xff0c;它提供了一种有趣的方式来介绍编程和图形绘制的基本概念。Turtle库使用一个虚拟的“海龟”来绘制图形。你可以控制海龟的方向、速度和位置&#xff0c;通过向前移动、向左转或向右转等命令来绘制线条、圆弧多边形等图形。 -----…

Java 反射(一)

反射 1.反射的介绍 1.反射机制允话程序在执行期间借助于Refelction API取得任何类的信息&#xff08;比如成员变量&#xff0c;构造器&#xff0c;成员方法等&#xff09;并能操作对象的属性及方法&#xff0c;反射在设计模式和框架底层都会用到 2.加载完类之后&#xff0c;在…

API调试怎么做?Apipost快速上手

前言 Apipost是一款支持 RESTful API、SOAP API、GraphQL API等多种API类型&#xff0c;支持 HTTPS、WebSocket、gRPC多种通信协议的API调试工具。除此之外&#xff0c;Apipost 还提供了自动化测试、团队协作、等多种功能。这些丰富的功能简化了工作流程&#xff0c;提高了研发…

mybatis注意事项/异常

一&#xff1a;mybatis Plus自动拼装sql异常 Error Sql/mybatisplus框架方法失效 Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: " 常见场景&#xff1a; 1.1XML使用了跟框架同名方法&#xff0c;例如selectLis…

CodeWave智能开发平台--03--目标:应用创建--08联系人管理

摘要 本文是网易数帆CodeWave智能开发平台系列的第11篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;实现一个完整的应用&#xff0c;本文主要完成08联系人管理 CodeWave智能开发平台的11次接触 CodeWave参考资源 网易数帆CodeWave开发者社区…

MongoDB:count结果不准确的原因与解决方法

教训&#xff1a;MongoDB在分片后的集合上进行db.collection.count()操作时&#xff0c;出现结果不准确的现象&#xff0c;需要采用聚合的方法获取集合的count结果 使用该命令依然会出现统计信息不准确的现象&#xff0c;通过谷歌发现&#xff0c;官方文档:(https://docs.mongo…

【VRTK】【Unity】【VR开发】Linear Drives

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 前面一篇讨论了角度运动机制,本篇讨论线性运动机制。和角度运动机制类似,线性运动机制提供了更为仿真的互动机制。也分为基于物理的和不基于…

doris部署

doris-2.0.1.1部署安装 一、下载doris安装包二、解压到/data下&#xff0c;修改名称三、修改fe配置文件四、启动doris-fe五、验证doris-fe六、修改be配置文件七、启动doris-be八、mysql中连接be&#xff0c;在Doris中添加后端节点九、设置密码 一、下载doris安装包 wget https…

ArrayBlockingQueue原理探究

类图结构 同样&#xff0c;为了能从全局一览ArrayBlockingQueue的内部构造&#xff0c;先来看它的类图。 ArrayBlockingQueue的内部有一个数组items,用来存放队列元素&#xff0c;putindex变量表示入队元素下标&#xff0c;takelndex是出队下标&#xff0c;count统计队列元素个…