简单谈谈React中的路由系统
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等。
pnk pnk被渲染称一个a标签,通常以声明式的方式被定义在应用程序中。
route route包含一个path,并指明了在path与url匹配时要渲染的组件。
router
如果说我们的应用程序是一座小城的话,那么route就是一座座带有门牌号的建筑物,而pnk就代表了到某个建筑物的路线。有了路线和目的地,那么就缺一位老司机了,没错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/ 开头。这种情况下我们总不能每次定义pnk和route的时候都带上admin吧?react-router已经考虑到了这种情况,所以为我们提供了一个basename属性。为browserrouter设置了basename之后,pnk中就可以省略掉admin了,而最后渲染出来的url又会自动带上admin。
<browserrouter basename="/admin"/> ... <pnk to="/home"/> // 被渲染为 <a href="/admin/home" rel="external nofollow" > ... </browserrouter>
对于web应用,browserrouter是我们的首选。但是这里还有一些browser router其他的兄弟姐妹,在其他的一些情况下你或许会用得到。
hashrouter 这个内部使用window.location.hash,由于这里存在一些问题,因此官方推荐使用browserrouter来替代。
memoryrouter 主要用在reactnative这种非浏览器的环境中,因此直接将url的history保存在了内存中。
staticrouter 主要用于服务端渲染。
link
link就像是一个个的路牌,为我们指明组件的位置。pnk使用声明式的方式为应用程序提供导航功能,定义的link最终会被渲染成一个a标签。pnk使用to这个属性来指明目标组件的路径,可以直接使用一个字符串,也可以传入一个对象。
// 字符串参数 <pnk to="/query">查询</pnk> // 对象参数 <pnk to={{ pathname: '/query', search: '?key=name', hash: '#hash' }}>查询</pnk>
link提供的功能并不多,好在我们还有navpnk可以选择。navpnk是一个特殊版本的link,可以使用activeclassname来设置pnk被选中时被附加的class,使用activestyle来配置被选中时应用的样式。此外,还有一个exact属性,此属性要求location完全匹配才会附加class和style。这里说的匹配是指地址栏中的url和这个link的to指定的location相匹配。
// 选中后被添加class selected <navpnk to={'/'} exact activeclassname='selected'>home</navpnk> // 选中后被附加样式 color:red <navpnk to={'/gallery'} activestyle={{color:red}}>gallery</navpnk>
route
route应该是react-route中最重要的组件了,它的作用是当location与route的path匹配时渲染route中的component。如果有多个route匹配,那么这些route的component都会被渲染。
与pnk类似,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是pght,<home />会被渲染 // 在不匹配时,容器的calss是dark,<about />会被渲染 <route path='/home' children={({ match }) => ( <div classname={match ? 'pght' : 'dark'}> {match ? <home/>:<about>} </div> )}/>
所有路由中指定的组件将被传入以下三个props。
match.
location.
history.
这里主要说下match.params.透过这个属性,我们可以拿到从location中解析出来的参数。当然,如果想要接收参数,我们的route的path也要使用特殊的写法。
如下示例,三个pnk是一个文章列表中三个链接,分别指向三篇id不同的文章。而route用于渲染文章详情页。注意path='/p/:id' ,location中的对应的段会被解析为id=1 这样的键值。最终这个键值会作为param的键值存在。route中的组件可以使用this.props.match.params.id来获取,示例中使用了结构赋值。
<pnk to='/p/1' /> <pnk to='/p/2' /> <pnk 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中的路由系统就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。