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,因为它更灵活。
首先,导航守卫在业务层面可能有三种表现:
- 根据状态(如登录/未登录)和身份(等级)将路由进行限制。低等级的用户根本没有定义某些路由。
- 路由在任何时候都是完整的,只是根据状态和身份,将入口进行限制(某些Link组件不显示)。没有任何操作能够导向没有权限访问的路由地址。
- 不对入口进行限制,根据状态和身份,将某些特定的路由添加拦截。
在这几种表现中,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
React-router总结相关推荐
- React router 的 Route 中 component 和 render 属性理解
React router 的 Route 中 component 和 render 属性理解 Route 标签的三个互斥属性 render.component.children Route 就是用来匹 ...
- router路由react_使用React Router在React中受保护的路由
router路由react In this video, you will see how to create a protected route using React Router. This r ...
- hitchhiker部署_Hitchhiker的React Router v4指南:无限远的递归路径!
hitchhiker部署 Welcome to the third part of the Hitchhiker's Guide to React Router v4. In this article ...
- [React Router v4] Intercept Route Changes
If a user has entered some input, or the current Route is in a "dirty" state and we want t ...
- 使用React Router以编程方式导航
通过react-router我可以使用Link元素来创建由react路由器本地处理的链接. 我在内部看到它调用this.context.transitionTo(...) . 我想从下拉列表中进行导航 ...
- 从 React Router 谈谈路由的那些事
React Router 是专为 React 设计的路由解决方案,在使用 React 来开发 SPA (单页应用)项目时,都会需要路由功能,而 React Router 应该是目前使用率最高的. Re ...
- [React Router v4] Conditionally Render a Route with the Switch Component
We often want to render a Route conditionally within our application. In React Router v4, the Route ...
- 初探 React Router 4.0
React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循React的设计理念,即万物皆组件.所以 RR4 只是一堆 提供了导航功能的组件(还有若干对象和方法),具有声明式(引入即用 ...
- React Router 使用教程
真正学会 React 是一个漫长的过程. 你会发现,它不是一个库,也不是一个框架,而是一个庞大的体系.想要发挥它的威力,整个技术栈都要配合它改造.你要学习一整套解决方案,从后端到前端,都是全新的做法. ...
- hitchhiker部署_《 Hitchhiker的React Router v4指南》:路由配置的隐藏值
hitchhiker部署 Welcome to the Hitchhiker's Guide to React Router v4, Part IV! 欢迎来到< React Router v4 ...
最新文章
- linux还原备份的内核镜像,使用Mondo制作Linux镜像(ISO)、还原系统图文详解
- 实时监听 input输入框值的变化 并响应动作
- LeetCode 126 单词接龙 II
- 系统分析员、系统架构师、项目经理的区别(转载)
- 建议收藏!前端工程师一线大厂面试2021总结篇(50个JS常问知识点)
- [日志]挂在树上的茶壶
- SQL语句详解(二)——select基本查询操作
- BZOJ2118[国家集训队] 墨墨的等式
- 淘宝 NPM 镜像解决软件下载速度慢的问题
- wordpress图文安装教程 非常详细
- 刘德华郑秀文喜剧大片《魔幻厨房》DVD国语中字
- springboot项目实现站内信功能记实
- STM32基于HAL工程读取DHT11/DHT22/AM2302/AM2301
- 最好的肠道菌群科普记录片
- 基于javaweb+jsp的设备维修管理系统(JavaWeb MySQL JSP Bootstrap Servlet SSM SpringBoot)
- 原型设计工具——“墨刀”的介绍与基本教程
- 智力杂志智力杂志社智力编辑部2023年第6期目录
- MSDN Webcast所有视频讲座的下载地址
- Git学习笔记及一些问题(廖雪峰版)
- 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法
热门文章
- 天然气阶梯是按年还是按月_按年算账 多退少补 你的年度个税应该是怎么算?...
- Exercising Walk CodeForces - 1332A(思维)
- A Simple Math Problem(矩阵快速幂)
- python开源项目homeassistant_树莓派安装家庭助理,Homeassistant,HASS
- ffplay android 编译,ffmpeg android 平台编译
- 【论文阅读】A Gentle Introduction to Graph Neural Networks [图神经网络入门](7)
- matlab png转02,matlab把图片pgm格式转换成png格式
- java中检测数据波动_在pyspark数据帧中检测异常值
- 数学--数论--HDU 12151七夕节
- 最小树形图+朱刘算法