资讯专栏INFORMATION COLUMN

[ 一起学React系列 -- 11 ] React-Router4 (1)

tinysun1234 / 1257人阅读

摘要:中的包中的包主要有三个和。的理念上面提到的理念是一切皆组件以下统一称组件。从这点来说的确方便了不少,也迎合一切皆组件的理念。组件是中主要的组成单位,可以认为是或的路由入口。将该标示为严格匹配路由。的属性追加一条。

2019年不知不觉已经过去19天了,有没有给自己做个总结?有没有给明年做个计划?
当然笔者已经做好了明年的工作、学习计划;同时也包括该系列博客剩下的博文计划,目前还剩4篇:分别是两篇React-Router4和两篇immutability-helper。本篇是React-Router4的第一篇,在正式开始之前大家可以先看下实际效果,这是笔者用React-Router4写的例子。

React-Router4

实际上,笔者接触的第一个React中的路由模块就是React-Router,只不过当时还是v3版本。因为没有太多深入得学习研究,所以在这里不会对v4之前的版本作介绍或者评价(其实并不代表笔者对v4版本有深入的研究学习,汗...)。下面列举些React-Router4中需要知道的一些概念或者emmmm...小知识点。

React-Router4中的包

React-Router4中的包主要有三个react-router、react-router-dom和react-router-native。据考证(手动斜眼笑),React-Router4已经将前身切分了出来分别整合成了多带带的module。其实笔者一开始看到也挺懵逼的,这三个包到底是什么玩意?

react-router:“The core of React Router”。简单说就是逻辑代码。
react-router-dom:“DOM bindings for React Router”。这个模块不仅仅包含了react-router的模块,还包含了页面渲染功能,也就是可以在页面上显示。
react-router-native:“React Native bindings for React Router”。这个也很好理解,就是可以在React-Native中使用。
路由根节点

React-Router4的理念是一切皆组件React-router-dom则提供了两个路由根节点:HashRouter和BrowserRouter。

HashRouter: 通过hash值来对路由进行控制,而且你会发现一个现象就是url中会有个#,例如localhost:3000/#。对于笔者这种有强迫症的人来说怎么能忍?所以笔者就没再碰这个组件。
BrowserRouter: BrowserRouter就相对舒服点。它的原理是使用HTML5 history API (pushState, replaceState, popState)来使你的内容随着url动态改变的,而不会出现莫名其妙的#
React-Router4的理念

上面提到:React-Router4的理念是一切皆组件(以下统一称“组件”)。我们v4之前的版本都需要在一个js文件中配置整个项目的路由信息然后在App.js(以create-react-app脚手架创建的React项目为例)引入并使用。而在React-Router4中则将所有的功能以React组件的形式提供出来,意思就是说我们可以像使用普通组件一样使用路由组件并最终在项目中形成一棵路由树。在这里笔者要注重说下,一个项目中尽量只有一棵路由树,除非有特殊需求,否则的话会造成一些奇怪的问题。通俗点说就是不要在一棵树上栽另一棵树。下面用一张图来简单展示下React-Router4的使用:

如图是React-Router4使用规则和最简单的使用实践。
当然这种写法(我称它叫组件型路由,下同)和之前的配置型路由哪个更好用是青菜萝卜的问题,不需要太多纠结,自己喜欢就好。接下来的介绍都是笔者通过学习官方文档并做了一些实践后的心得。如有不当或者错误,欢迎指正。对于第一次学习该模块的童鞋,笔者建议将代码下载下来一遍看代码一遍看本文,也可以打开笔者的demo,这样会更深刻。

常用路由组件介绍

下面这段代码是该demo根路由配置的代码(其实不存在什么根路由概念,只是笔者喜欢这么叫它)。从这里就能明显看出来react-router3和4两个版本的差异。react-router3有自己独立的一个配置中心文件,而react-router4则把跳转的规则嵌入到实际代码中,不需要额外维护一个路由配置文件。从这点来说的确方便了不少,也迎合React一切皆组件的理念。


    

从这段代码中需要了解的概念包括:RouterNavLinkRouteRedirectexactSwitch

Router

上面已经介绍过了,这里笔者用的是BrowserRouter

NavLink

NavLink可以触发路由的跳转,当然类似的组件还有Link。它们都可以通过指定属性to的值来告诉Router我们要跳转到那个Route,实际上NavLink(Link)Route本就已经通过topath两个属性建立起关系了。而NavLink与Link的区别在于各自API的数量,因为NavLink可用的API相对较多,所以笔者更青睐NavLink。具体API有兴趣的可以自行Google,常用的API笔者已经在项目中使用。

Route

Route组件是React Router4中主要的组成单位,可以认为是NavLink或Link的路由入口。在这里笔者要重点Tip一下,上一条说NavLink或Link可以触发路由的跳转,实际上它们的实现流程是这样的:

NavLink(Link)改变地址栏的pathname,Router会根据pathname去匹配它子组件中的Route中的path属性,一旦匹配上就会渲染该Route对应的组件`。所以NavLink(Link)与Route并没有并存的关系,因为NavLink(Link)只是用来改变pathname,不会直接去调用任何API。所以当我们在地址栏直接手动输入路由,也会发生路由渲染。

具体匹配规则请参考path-to-regexp,或者通过这个网站进行测试。

Redirect

Redirect相当于转发器。Router内部去匹配路由入口的时候也会去匹配Redirect的from属性值。一旦匹配到了Redirect,Redirect就会将这个跳转请求转向自己的to属性值对应的路由。所以这个过程可以这样理解:当我们访问页面路径的时候,比如:http://ip:3001/,就会捕获到"/"这个路由跳转请求,Router开始在Route中匹配随后匹配到了Redirect,Redirect自行发起路由跳转请求"/basic",Router开始像往常一样在Route中匹配直到匹配到了path为"/basic"的Route,随后对Route对应的component进行渲染。

exact

exact将该Route标示为严格匹配路由。什么叫严格匹配路由?就是pathname必须与Route的path属性值完全一致才算匹配上。例如:

pathname path 匹配结果
/home /home 可以匹配
/home/child /home 无法匹配
这里Tip下:
如果某个Route对应的组件中也有Route,那么千万不要 在这个Route中加 exact,不然你会发现完全匹配不到子路由。切记,因为笔者最近刚踩过这个坑。所以这里笔者建议大家只在叶子Route中使用exact,也就是最后一级Route中使用exact,当然 exact "/" 除外
Switch

Switch可以将多个Route包裹成一组Route,当进行路由匹配时候,该组中的路由一旦发生匹配那么就不会匹配改组中剩下的路由。也就是说该组中的路由最多只会被匹配到一个

Route的component属性

追加一条。
Route的component属性对应的属性值通常是一个组件或者一个方法。而如果是方法的话,比如例子中:

const renderBasicRouter = ({ match }) => ;

那么传入的参数为:

所以如果在跳转前有什么特殊逻辑需要处理,比如我们想让不同的页面有不同的前缀,比如例子中的/basic/Home/param/home等,那么就可以如例子一样处理。
但如果不需要特殊处理的话,直接把组件放到component属性下即可。当然router相关的参数也会通过props传给该组件。

这里Tip下:
1、Route中还有一个render属性,也可以用来渲染组件,但是当我们渲染被Redux处理过的组件时候可能会有问题,因为Redux会在原组件基础上多包裹一层。
2、如果

当然常用路由组件还不仅仅这些,后续例子会有补充。

基础路由

基础路由的使用比较简单,前面的介绍其实已经把它基础使用方法已经说了。不过笔者这里有个小tip:

match.url 常用于NavLink或者Link中拼接路由路径,比如:
match.path常用于Route中拼接路由入口路径,比如:
这里Tip下:
当URL中不带有任何参数的时候,match.path和match.url完全一致。如果带有参数的话可能会有点编码上的差异。
带参路由

带参路由在实际开发中用的比较多,这里只介绍location.pathname中的参数,location.search笔者没有研究过所以就不说了,免得误导大家。我们可以先看下demo例子的部分代码:


这里可以看到Route的配置有点不同,用过express的朋友都知道,路由中通过 :xxx 来标示这是一个参数。其实这里也一样。如例子所示我们在 path={${PATH}/name/:name}通过 :name 来标示这是一个参数。然后对应的导航也有 to={${URL}/name/Mario}。所以这个流程就相当于:导航到/name路由并且传 name为Mario的参数。这个参数可以在对应组件的props中拿到(this.props.match.prams.name)。我们还看到 path={${PATH}/check/:check(true|false)},在参数后有个括号并且里面还有管道符,其实这是限定check的参数值必须为true或者false这两个。细心的朋友可能注意到,我在每个Route中加了exact,这样做的好处是可以不用考虑Route的放置次序。举个例子解释下:如果我们想查看某个人的信息,那么跳转路由应该是 /user/4,但如果Route中有:


    
    

那么/user/4就会在匹配到/user后停下渲染User组件并且忽略了参数。有人说把Switch去掉不就行了吗?并不是,那么/user/4会同时匹配上这两个路由并且什么都不会渲染,因为它懵逼了,不知道渲染哪个。所以这种情况下需要调整它们的位置


    
    

这样就不会出现上述问题了。但是如果在每一个Route中使用exact(前提是这个Route是叶子Route),就不用考虑Route的次序问题了。

404路由

有时候会由于各种问题出现匹配不到任何Route的情况,这个时候为了更好的用户体验,我们会配置一个404路由,形如:

不过笔者发现在根路由中配置一个404后无法全局抓取路由404,不知道是本就如此还是用法有误,所以笔者在每一级路由中都配置了 。写法很简单,照着写就好了,component中传入显示404信息的组件即可。

顺便加一下demo源码

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101210.html

相关文章

  • [ 一起React系列 -- 12 ] React-Router4 (2)

    摘要:验证路由所谓的验证路由其实就是该路由的外层加了一层验证机制,有授权的用户才能进入,反之都无法进入。一起学系列也随着这篇的结束而告一段落了。大家一起加油最后再献上和本篇博文有关的代码链接和示例页面 时隔那么久,博主终于从睡梦中醒来开始更新博客啦!为自己的勤劳欢呼...(pia pia pia打脸)!本次我们接着上一篇博客继续聊React-Router4。上篇我们主要了解了React-Ro...

    chaos_G 评论0 收藏0
  • 前端习资源整理

    稍微整理了一下自己平时看到的前端学习资源,分享给大家。 html MDN:Mozilla开发者网络 SEO:前端开发中的SEO css 张鑫旭:张鑫旭的博客 css精灵图:css精灵图实践 栅格系统:详解CSS中的栅格系统 媒体查询:css媒体查询用法 rem布局:手机端页面自适应布局 移动前端开发之viewport的深入理解:深入理解viewport 淘宝前端布局:手机淘宝移动端布局 fl...

    siberiawolf 评论0 收藏0
  • 前端综合性文档和教程总结(持续更新)

    摘要:小弟在前端摸爬滚打一段时间,发现前端的比较好的文档比较分散,特别是中文的,我平时都是收藏在浏览器里,以后有好的教程和综合性的文档我会更新到这里。小组中文文档,很全。 小弟在前端摸爬滚打一段时间,发现前端的比较好的文档比较分散,特别是中文的,我平时都是ctrl+D收藏在浏览器里,以后有好的教程和综合性的文档我会更新到这里。一则可以做个记录,防止丢失。二则有需要的朋友可以来我这里找一找。 ...

    piglei 评论0 收藏0
  • React 可视化开发工具 Shadow Widget 非正经入门(之一:React 三宗罪)

    摘要:前言非正经入门是相对正经入门而言的。不过不要紧,正式学习仍需回到正经入门的方式。快速入门建议先学会用拼文写文档注册一个账号,把库到自己名下,然后用这个库写自己的博客,参见这份介绍。会用拼文写文章,相当于开发已入门三分之一了。 本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点,既作为用户手册的补充,也从更本质角度帮助大家理解 Shadow Widget 为什么这...

    dongxiawu 评论0 收藏0

发表评论

0条评论

tinysun1234

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<