React-router总结

版本

v3和v4有一些差距:

https://blog.csdn.net/qq_35484341/article/details/80500237

以下的总结,都是基于V4的

官方文档:https://reacttraining.com/react-router/web/guides/quick-start

核心组件和用法

<BrowserRouter/>   
<HashRouter/>
<Route/>
<Switch/>
<Redirect/>
<Link/> (<NavLink/>)
withRouter

不多解释,先上实例:

<BrowserRouter><Link to="/">主页</Link><Link to="/recommend">推荐</Link><Link to="/detail/1">详情</Link><Route path="/" exact component={Home}/><Route path="/detail/:id" exact component={Detail}/><Route path="/recommend" exact component={Recomm}/>
</BrowserRouter>

BrowserRouter和HashRouter

这两者可以理解为路由的作用域,所有的Link组件和Route组件都必须在其内部。

浏览器路由和哈希路由的区别:

  • BrowserRouter中的URL指向真实的url,当页面刷新(或直接操作url并回车)时,将产生指向该路径的url请求,如果服务器端没有配置该路径,则返回404。在项目上线后,需要我们去配置服务端。(通过Link并不会向后端发送真实请求)
  • HashRouter中#后面的uri并不是真实的请求路径,对于后端来说,全都指向同一个地址。另外哈希历史记录不支持loaction.key和loaction.state,当通过state传递参数的时候,无法从历史记录中获取到,可能会导致页面显示异常。

在BrowserRouter模式下,如何在服务端配置呢?

  • Nginx配置(前端项目打包),将任何URL访问都指向index.html
  • 后端服务配置(前端项目打包),将任何URL访问都指向index.html
  • 开启前端服务(需要进行Nginx反向代理)

Link

被渲染成a标签,跟href属性的所用类似。点击Link标签和a标签,看到的效果是一样的,但我们推荐<Link>,使用它才是单页面应用,浏览器不会请求页面;而使用a标签,会重新请求页面。

<Link to='/path' />
<Link to={pathname, // 路径,即 to 的字符串用法search,  // searchhash,  // hashstate,  // state 对象action,  // location 类型,在点击 Link 时为 PUSH,浏览器前进后退时为 POP,调用 replaceState 方法时为 REPLACEkey,  // 用于操作 sessionStorage 存取 state 对象
} />
<Link to='/path' replace={true} /> // 覆盖当前路径

NavLink

Link的加强版

  • activeClassName(string):设置选中样式,默认样式名为active
  • activeStyle(object):当元素被选中时,为此元素添加样式
  • exact(bool):为true时,只有当导致和完全匹配class和style才会应用
  • strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
  • isActive(func):判断链接是否激活的额外逻辑的功能。可以做导航守卫

Route

具体的路由规则

属性:

// 渲染目标
component // 渲染组件
render  
children// 地址匹配
path
<Route path="/hello/:name"> 
name为参数名,可以在其渲染组件中获取 this.props.params.name
<Route path="/files/*.*">
匹配 /files/hello.jpg  、   /files/hello.html
<Route path="/files/*">
匹配 /files/  、 /files/a   、 /files/a/bexact  // 完全匹配的意思,排他

Switch

有<Switch>嵌套,则其中的<Route>在路径相同的情况下,只匹配第一个,这个可以避免重复匹配。

无<Switch>嵌套,则其中的<Route>在路径相同的情况下全都会匹配,包括上级路径。

Rediret

重定向到新地址

<Redirect to='/path' />

Prompt

当用户准备离开该页面时,弹出提示

message: 字符串/函数,离开页面时的提示信息
when:布尔值,通过设定条件决定是否启用该组件

例如:

<Prompt message="您确定要离开该页面吗?" when={this.state.isOpen} />
<Promptmessage = {() => {this.state.isOpen? false: "您确定要离开该页面吗?"}}
/>

对象和方法 

被Route绑定的渲染组件,总是被传入三个属性(对象):history、location、match。在渲染组件中也会有很多其他组件,这些组件内部如果想要获取三个对象,需要withRouter(通过装饰器或函数调用的形式都可)。

我们可以用这三个对象完成很多事情。

history

history实现对会话历史的管理。

length: number   浏览历史堆栈中的条目数
action: string   路由跳转到当前页面执行的动作,分为 PUSH, REPLACE, POP
location: object   当前访问地址信息组成的对象,具有如下属性:
pathname: string   URL路径
search: string   URL中的查询字符串
hash: string   URL的 hash 片段
state: string   例如执行 push(path, state) 操作时,location 的 state 将被提供到堆栈信息里,state 只有在 browser 和 memory history 有效。
push(path, [state])   在历史堆栈信息里加入一个新条目。
replace(path, [state])   在历史堆栈信息里替换掉当前的条目
go(n)   将 history 堆栈中的指针向前移动 n。
goBack()   等同于 go(-1)
goForward   等同于 go(1)
block(prompt)   阻止跳转

location

loaction指当前的位置

{hash: '#sdfas',key: 'sdfad1'pathname: '/about',search: '?name=minooo'state: {price: 123}
}

可以在不同场景中使用:

<Link to={location} />
<NaviveLink to={location} />
<Redirect to={location />
history.push(location)
history.replace(location)

match

match对象包含了<Route>如何与URL匹配的信息。

params: object 路径参数,通过解析 URL 中的动态部分获得键值对
isExact: bool 为 true 时,整个 URL 都需要匹配
path: string 用来匹配的路径模式,用于创建嵌套的 <Route>
url: string URL 匹配的部分,用于嵌套的 <Link>

路由之间的传值

大致有三种方法:

params

//路由设置
<Route path=' /user/:id '   component={User} />
// 传值
<Link to='/user/2' />
this.props.history.push("/user/2");
// 获取值
this.props.match.params.id

URL参数

//路由设置
<Route path=' /user '   component={User} />
// 传值
<Link to='/user?id=2' />
this.props.history.push("/user?id=2");
// 获取值
this.props.location.seacrh // 获得"?id=2",将其进行拆解即可获得

location对象(哈希路由无法利用)

又有两种方式:

(1)loaction.state。传的参数是加密的

// 路由设置
<Route path=' /user '   component={User}></Route>
// 传值
<Link to={{ pathname:' /user',state:{id:123},search:'?sort=name',hash:'#the-hash'}}> 
this.props.history.push({pathname:' /user',state:{id:123},search:'?sort=name',hash:'#the-hash'});
// 获取值
this.props.location.state.id

(2)自定义属性

// 路由设置
<Route path=' /user '   component={User}></Route>
// 传值
<Link to={{ pathname:' /user',abc:{id:123},search:'?sort=name',hash:'#the-hash'}}> 
this.props.history.push({pathname:' /user',abc:{id:123},search:'?sort=name',hash:'#the-hash'});
// 获取值
this.props.location.abc.id

导航守卫的实现

在react-router中,并没有提供导航守卫相关的API,作者这样描述:你可以在渲染功能中实现此功能,JSX不需要API,因为它更灵活。

首先,导航守卫在业务层面可能有三种表现:

  1. 根据状态(如登录/未登录)和身份(等级)将路由进行限制。低等级的用户根本没有定义某些路由。
  2. 路由在任何时候都是完整的,只是根据状态和身份,将入口进行限制(某些Link组件不显示)。没有任何操作能够导向没有权限访问的路由地址。
  3. 不对入口进行限制,根据状态和身份,将某些特定的路由添加拦截。

在这几种表现中,2和3并不相互冲突。现在有两种思路实现导航守卫:

  • 写一个路由配置表,写一个高阶组件,导航守卫的功能由高阶组件完成,所有与路由绑定的组件都被高阶组件修饰。(对应业务场景3)
  • 写一个路由配置表,定义一个组件:根据路由配置生成最终的<Route>。对于用户没有权限的路由,可以控制不将其渲染。(对应业务场景1)
  • 写一个路由配置表,写一个高阶组件,将是否渲染入口的逻辑写在高阶组件中,所有可能被隐藏的入口都被此高阶组件修饰。(对应业务场景2)

示例1(业务场景1):

// 路由配置
const routerConfig = [{path:'/',component:HomePage,auth:false, },{path:'/home',component:HomePage,auth:true, // 表示必须登录才能访问},{path:'/login',component:LoginPage,},{path:'/404',component:ErrorPage}
];class RouterTab extends React.Component{render(){return(<HashRouter><Switch><RouteGenerator config={routerConfig} /></Switch></HashRouter>);}
}class RouterGenerator extends React.Coponent{// 在这里定义限制路由的逻辑(业务场景1)render(){const routeConf = this.props.config;routeConf.map((conf)=>{if(conf.auth) // 判断该路由是否满足渲染条件{if(login) // 判断当前有没有登录{retrun <Route path={conf.path} component={conf.component} exact={conf.exact?true:false} />}}else{retrun <Route path={conf.path} component={conf.component} exact={conf.exact?true:false} />}});}
}

示例2(业务场景3):

// 将此高阶组件修饰所有需要被守卫的路由组件
const routerGuard = (RouteConfig) => {retrun (WrappedComponent) => {rentrun class NewComponent extends React.Component {componentWillMount(){const path = this.props.location.pathname;const config = RouteConfig.find(f => f.path === path);if(!config){this.props.history.push("/404");}if(config.auth && !login){this.props.history.push("/login");}}render(){retrun(<WrappedComponent {...this.props} />)}}}
}

路由的异步加载 

如果项目特别大,打包后的js文件会特别大。在首次加载时,一次性地将整个js文件发送给浏览器,一次性地加载所有代码,会对浏览器产生比较大的压力,影响用户体验。我们希望的是,只加载当前访问页面相关的js代码,当路由跳转的时候,再请求相应页面的js代码。这需要使用第三方库,做的比较优秀的有 react-loadable 和 react-async-component。

react-loadable的原理是将代码进行分割,分割成若干个chunk.js,需要用到的时候就请求过来。

react-async-component为按需异步加载,使用Promise和高阶组件实现,提高性能。

 

转载于:https://www.cnblogs.com/V587Chinese/p/11507836.html

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

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

相关文章

机器学习之 weka学习(一)weka介绍,安装和配置环境变量

本部分详情可查看博客http://blog.csdn.net/u011067360/article/details/20844443 数据挖掘开源软件&#xff1a;WEKA基础教程 Weka简介&#xff1a; Weka是由新西兰怀卡托大学开发的智能分析系统&#xff08;Waikato Environment for Knowledge Analysis&#xff09; 。在怀…

第一章:线性空间和线性变换

转载于:https://www.cnblogs.com/invisible2/p/11514817.html

机器学习之 weka学习(二)算法说明

本文转自&#xff1a;http://blog.csdn.net/mm_bit/article/details/47405433 weka中的各算法说明 1) 数据输入和输出 WOW()&#xff1a;查看Weka函数的参数。 Weka_control()&#xff1a;设置Weka函数的参数。 read.arff()&#xff1a;读Weka Attribute-Relation File Forma…

TypeScript泛型

泛型的概念 指不预先确定的数据类型&#xff0c;具体的类型要在使用的时候才能确定。咋一听&#xff0c;是不是觉得JavaScript本身就是这样&#xff1f;这是由于理解有误。前面说“在使用的时候确定”&#xff0c;而非在程序执行的时候确定。 泛型函数 现在有个需求&#xff1a…

TypeScript类型检查机制

类型推断 指不需要指定变量的类型&#xff0c;TS编译器可以根据某些规则自动推断出类型。 什么时候会有类型推断&#xff1f; 声明变量时没有指定类型函数默认参数函数返回值......let a; // 这时自动推断为any类型 let b 1; // 推断为number类型 let c []; // 推断为由any类…

机器学习之 weka学习(三)

本文转自&#xff1a;http://blog.csdn.net/qiao1245/article/category/6115745 Weka教程笔记 http://blog.csdn.net/qiao1245/article/category/6115745 使用Weka进行数据挖掘&#xff08;Weka教程二&#xff09;Weka数据之ARFF与多文件格式转换 http://blog.csdn.net/qiao…

机器学习之 weka学习(四)

本文转自&#xff1a; http://blog.csdn.net/lantian0802/article/details/8875874 http://blog.csdn.net/lkj345/article/details/50152055 点击最上方的Classify按钮&#xff0c;选择Logistic&#xff08;逻辑回归&#xff09;分类方法&#xff0c;在Test options中选择…

TypeScript模块系统、命名空间、声明合并

命名空间 命名空间能有效避免全局污染。在ES6引入模块之后&#xff0c;命名空间就较少被提及了。如果使用了全局的类库&#xff0c;命名空间仍是一个好的解决方案。 namespace Shape{const pi Math.PI;// 使用export关键字导出&#xff0c;可以在全局空间内可见export functio…

机器学习之 weka学习(五)示例用法

WEKA 开发学习 &#xff1a;源码法分析 http://www.360doc.com/userhome.aspx?userid13256259&cid11# 用 WEKA 进行数据挖掘 http://www.ibm.com/developerworks/cn/opensource/os-weka1/WEKA使用教程 http://blog.csdn.net/yangliuy/article/details/7589306 初试w…

如何在TypeScript中使用JS类库

使用流程 1.首先要清除类库是什么类型&#xff0c;不同的类库有不同的使用方式 2.寻找声明文件 JS类库一般有三类&#xff1a;全局类库、模块类库、UMD库。例如&#xff0c;jQuery是一种UMD库&#xff0c;既可以通过全局方式来引用&#xff0c;也可以模块化引用。 声明文件 当我…

机器学习之 weka学习(六)最大内存

Weka 常见问题处理&#xff1a; weka如何安装支持向量机工具包 方法一、打开 weka&#xff0c;工具栏的Tools–>Package manager,可在里面添加需要的工具包。 方法二、下载 libsvm-**.jar 包&#xff0c;开源的。解压文件夹&#xff0c;里面……\libsvm-3.19\java ,下面有…

使用Jest进行单元测试

Jest是Facebook推出的一款单元测试工具。 安装 npm install --save-dev jest ts-jest types/jest 在package.json中添加脚本&#xff1a; “test”: "jest" 生成Jest配置文件&#xff08;生成jest.config.js&#xff09; npx ts-jest config:init 使用 先简单编写一个…

国外十大高校人工智能实验室及其代表性人物一览

本文转自&#xff1a; http://toutiao.com/a6293031494186107137/?tt_frommobile_qq&utm_campaignclient_share&appnews_article&utm_sourcemobile_qq&iid4325464459&utm_mediumtoutiao_android 高校建立的实验室与大公司有所不同&#xff0c;其研究项目…

pytorch简单框架

网络搭建&#xff1a; mynn.py: import torchfrom torch import nnclass mynn(nn.Module): def __init__(self): super(mynn, self).__init__() self.layer1 nn.Sequential( nn.Linear(3520, 4096), nn.BatchNorm1d(4096), nn.ReLU(True) …

java 基础安装和Tomcat8配置

初识 java&#xff0c;基础安装的说明。 下载 在oracle官网一般在同一个java版本会提供2个版本&#xff0c; 一个是Java SE Development Kit 7u80&#xff0c;此版本包含JDK开发环境版本&#xff1b; 另外一个是 Java SE Runtime Environment 7u80&#xff0c;此为只包含JR…

TypeScript React

环境搭建 我们当然可以先用脚手架搭建React项目&#xff0c;然后手动配置成支持TypeScript的环境&#xff0c;虽然比较麻烦&#xff0c;但可以让你更清楚整个过程。这里比较麻烦&#xff0c;就不演示了&#xff0c;直接用命令配置好。 npx create-react-app appname --typescri…

matlab内存溢出的解决方案

&#xff08;1&#xff09; 增加虚拟内存&#xff1a;cmd -> taskmgr 打开任务管理器&#xff0c;查看物理内存和虚拟内存&#xff0c;可观察matlab在运行过程中是否超过物理内存和虚拟内存。若超过&#xff0c;增加虚拟内存的方法是不可行的。物理内存不足的时候可以通过将…

c++MMMMM:oo

1.union&#xff0c;struct和class的区别 转载于:https://www.cnblogs.com/invisible2/p/11524465.html

matlab调用Java程序时出现 Java.lang.OutOfMemoryErrot: GC overhead limit exceeded

matlab调用Java程序时出现 java.lang.OutOfMemoryError: GC overhead limit exceeded JDK1.6.0_37和JDK_1.7.0_60版本&#xff0c;这2个版本中JVM默认启动的时候-XX:UseGCOverheadLimit&#xff0c;即启用了该特性。这其实是JVM的一种推断&#xff0c;如果垃圾回收耗费了98%的…

[FY20 创新人才班 ASE] 第 1 次作业成绩

作业概况 条目备注作业链接【ASE高级软件工程】热身作业&#xff01;提交人数19未完成人数2满分10分作业情况总结 本次作业作为大家软工课程的第一次作业&#xff0c;完成度相当不错&#xff08;尤其是在国外暑研/赶论文的同学也在尽力完成作业&#xff0c;很感动&#xff09;。…