React中的路由系统
提起路由,首先想到的就是 ASPNET MVC 里面的路由系统--通过事先定义一组路由规则,程序运行时就能自动根据我们输入的URL来返回相对应的页面。前端中的路由与之类似,前端中的路由是根据你定义的路由规则来渲染不同的页面/组件,同时也会更新地址栏的URL。本篇文章要介绍的是React中经常使用到的路由,react-router主要使用HTML5的history API来同步你的UI和URL。
react-router的最新版本是v4.1.1,由于4.0版本和之间的版本API变化较大,所以本篇文章的内容并不能应用到之前的版本中。
要注意
react-router有react-router-dom和react-router-native的区别。前者是用于开发WEB应用的,而后者适用于移动APP的,本文所介绍的是react-router-dom。
react-router 中的三大组件
react-router中的组件就是react中的组件,只不过它们被添加了一些特殊的逻辑而已。
- Router Router相当于一个容器,不会被渲染出来。你的其他组件都要放在Router中才能使用到react-router的功能。根据功能的不同,Router还分为BrowserRouter,MemoryRouter等。
- Link Link被渲染称一个a标签,通常以声明式的方式被定义在应用程序中。
- Route Route包含一个path,并指明了在path与URL匹配时要渲染的组件。
Router
如果说我们的应用程序是一座小城的话,那么Route就是一座座带有门牌号的建筑物,而Link就代表了到某个建筑物的路线。有了路线和目的地,那么就缺一位老司机了,没错Router就是这个老司机。
先来说一说BrowserRouter。BrowserRouter主要使用在浏览器中,也就是WEB应用中(废话,看名字就知道了)。它利用HTML5 的history API来同步URL和UI的变化。当我们点击了程序中的一个链接之后,BrowserRouter就会找出与这个URL匹配的Route,并将他们渲染出来。 既然BrowserRouter是用来管理我们的组件的,那么它当然要被放在最顶级的位置,而我们的应用程序的组件就作为它的一个子组件而存在。
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.body);
有时候我们的应用只是整个系统中的一个模块,比如一个使用了ASPNET MVC中的area的后台管理模块,应用中的URL总是以 http://localhost/admin/ 开头。这种情况下我们总不能每次定义Link和Route的时候都带上admin吧?react-router已经考虑到了这种情况,所以为我们提供了一个basename属性。为BrowserRouter设置了basename之后,Link中就可以省略掉admin了,而最后渲染出来的URL又会自动带上admin。
<BrowserRouter basename="/admin"/>
...
<Link to="/home"/> // 被渲染为 <a href="/admin/home">
...
</BrowserRouter>
对于WEB应用,BrowserRouter是我们的首选。但是这里还有一些Browser Router其他的兄弟姐妹,在其他的一些情况下你或许会用得到。
- HashRouter 这个内部使用window.location.hash,由于这里存在一些问题,因此官方推荐使用BrowserRouter来替代。
- MemoryRouter 主要用在ReactNative这种非浏览器的环境中,因此直接将URL的history保存在了内存中。
- StaticRouter 主要用于服务端渲染。
Link
Link就像是一个个的路牌,为我们指明组件的位置。Link使用声明式的方式为应用程序提供导航功能,定义的Link最终会被渲染成一个a标签。Link使用to这个属性来指明目标组件的路径,可以直接使用一个字符串,也可以传入一个对象。
// 字符串参数
<Link to="/query">查询</Link>
// 对象参数
<Link to={{
pathname: '/query',
search: '?key=name',
hash: '#hash'
}}>查询</Link>
Link提供的功能并不多,好在我们还有NavLink可以选择。NavLink是一个特殊版本的Link,可以使用activeClassName来设置Link被选中时被附加的class,使用activeStyle来配置被选中时应用的样式。此外,还有一个exact属性,此属性要求location完全匹配才会附加class和style。这里说的匹配是指地址栏中的URl和这个Link的to指定的location相匹配。
// 选中后被添加class selected
<NavLink to={'/'} exact activeClassName='selected'>Home</NavLink>
// 选中后被附加样式 color:red
<NavLink to={'/gallery'} activeStyle={{color:red}}>Gallery</NavLink>
Route
Route应该是react-route中最重要的组件了,它的作用是当location与Route的path匹配时渲染Route中的Component。如果有多个Route匹配,那么这些Route的Component都会被渲染。
与Link类似,Route也有一个exact属性,作用也是要求location与Route的path绝对匹配。
// 当location形如 http://location/时,Home就会被渲染。
// 因为 "/" 会匹配所有的URL,所以这里设置一个exact来强制绝对匹配。
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
Route的三种渲染方式
- component
这是最常用也最容易理解的方式,给什么就渲染什么。
- render
render的类型是function,Route会渲染这个function的返回值。因此它的作用就是附加一些额外的逻辑。
<Route path="/home" render={() => {
console.log('额外的逻辑');
return (<div>Home</div>);
}/>
- children
这是最特殊的渲染方式。一、它同render类似,是一个function。不同的地方在于它会被传入一个match参数来告诉你这个Route的path和location匹配上没有。二、第二个特殊的地方在于,即使path没有匹配上,我们也可以将它渲染出来。秘诀就在于前面一点提到的match参数。我们可以根据这个参数来决定在匹配的时候渲染什么,不匹配的时候又渲染什么。
// 在匹配时,容器的calss是light,<Home />会被渲染
// 在不匹配时,容器的calss是dark,<About />会被渲染
<Route path='/home' children={({ match }) => (
<div className={match ? 'light' : 'dark'}>
{match ? <Home/>:<About>}
</div>
)}/>
所有路由中指定的组件将被传入以下三个props。
- match.
- location.
- history.
这里主要说下match.params.透过这个属性,我们可以拿到从location中解析出来的参数。当然,如果想要接收参数,我们的Route的path也要使用特殊的写法。
如下示例,三个Link是一个文章列表中三个链接,分别指向三篇id不同的文章。而Route用于渲染文章详情页。注意path='/p/:id' ,location中的对应的段会被解析为id=1 这样的键值。最终这个键值会作为param的键值存在。Route中的组件可以使用this.props.match.params.id来获取,示例中使用了结构赋值。
<Link to='/p/1' />
<Link to='/p/2' />
<Link to='/p/3' />
......
<Route path='/p/:id' render={(match)=<h3>当前文章ID:{match.params.id}</h3>)} />
Redirect
当这个组件被渲染是,location会被重写为Redirect的to指定的新location。它的一个用途是登录重定向,比如在用户点了登录并验证通过之后,将页面跳转到个人主页。
<Redirect to="/new"/>
Router中常用的组件基本上都介绍了一遍,不过也只是蜻蜓点水而已。如果想更透彻的理解路由系统,建议还是去翻看官方文档并且试着去用一用。文中给出的示例也是非常精简的片段,仅仅作为参考。
React中的路由系统的更多相关文章
- Django中的路由系统:urls
Django的路由系统 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. 你就是以这种方式告诉Django,对于这个URL调用 ...
- django 中的路由系统(url)
路由系统 根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图.Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理 ...
- 第六篇 Flask中的路由系统
Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST" ...
- MVC3中的路由系统(Routes)
转载:http://blog.csdn.net/francislaw/article/details/7429317 MVC中,用户访问的地址并不映射到服务器中对应的文件,而是映射到对应Control ...
- ASP.NET MVC3中的路由系统 Routes
MVC中,用户访问的地址并不映射到服务器中对应的文件,而是映射到对应Control里对应的ActionMethod,由ActionMethod来决定返回用户什么样的信息.而把用户访问的地址对应到对应的 ...
- asp.net中的路由系统
ASP.NET MVC重写了ASP.NET管道HttpModule和处理程序HttpHandler.MVC自定义了MvcHandler实现了Controller的激活和Action的执行.但是在请求到 ...
- ASP.NET MVC3中的路由系统(Routes) .
MVC中,用户访问的地址并不映射到服务器中对应的文件,而是映射到对应Control里对应的ActionMethod,由ActionMethod来决定返回用户什么样的信息.而把用户访问的地址对应到对应的 ...
- Flask 中的路由系统
基本用法 Django的路由系统url集中在一起,而Flask的路由系统以装饰器的形式装饰在视图上如: @app.route("/",methods=["GET" ...
- react中的路由模块化
在vue中,可以将路由单独写在一个配置文件中,便于整理维护,而在前面总结整理的react中,都是直接将路由配置放在需要使用的地方,少数的时候话可以接受,但是当项目做大,这种方式就不再被推荐了,我们再r ...
随机推荐
- 高CPU、数据库无法读写的真凶
有兴趣的同学可以参考如下系列文章,都是针对dump分析的实战和总结: Windbg DUMP分析(原创汇总) http://www.cnblogs.com/LoveOfPrince/p/6653341 ...
- (转)关于BigDecimal 转化字符串toPlainString()和toString()的区别
对于 BigDecimal b ; (b=(0.4321)^ 20)String s = b.toPlainString() ;System.out.println(s) ; 输出为:0.0 ...
- ionic2新手入门整理,搭建环境,创建demo,打包apk,热更新,优化启动慢等避坑详解
onic官方文档链接:http://ionicframework.com/docs/ 如果是新的环境会有很多坑,主要是有墙,请仔细阅读每个步骤 文档包含以下内容: l 环境搭建 l 创建demo并 ...
- js获取页面宽高
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...
- MySQL基础语法------增删改查
1.增 1.1建立数据库 create database test2; 格式:create database <数据库名> 1.2建表 create table student( sno ...
- 使用EF连接Postgresql
环境: VS2017 Community Windows 10 Postgresql 9.6 安装Postgresql: https://www.postgresql.org/download/ 1. ...
- Python数据类型及其方法详解
Python数据类型及其方法详解 我们在学习编程语言的时候,都会遇到数据类型,这种看着很基础也不显眼的东西,却是很重要,本文介绍了python的数据类型,并就每种数据类型的方法作出了详细的描述,可供知 ...
- Swift json字典转模型 项目记录
背景 最近项目开始转用Swift3开发,由于Swift中json(字典)转模型的选择方案较多,笔者最开始选择了HandyJSON的方案,在使用一段时间后发现当要进行某个字段取值使用时需要进行各种的转化 ...
- AutoResetEvent类的使用
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号.如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set 发出资源可用的 ...
- 来吧学学.Net Core之登录认证与跨域资源使用
序言 学习core登录认证与跨域资源共享是越不过的砍,所以我在学习中同样也遇到啦这两个问题,今天我们就用示例来演示下使用下这2个技术点吧. 本篇主要内容如下: 1.展示一个登录认证的简单示例 2.跨域 ...
