简单谈谈React中的路由系统


Posted in Javascript onJuly 25, 2017

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匹配时要渲染的组件。

简单谈谈React中的路由系统

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中的路由系统就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一个符号插入器 中用到的js代码
Sep 04 Javascript
jQuery 使用手册(四)
Sep 23 Javascript
让mayfish支持mysqli数据库驱动的实现方法
May 22 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
Aug 24 Javascript
Javascript获取CSS伪元素属性的实现代码
Sep 28 Javascript
VUEJS实战之利用laypage插件实现分页(3)
Jun 13 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
Dec 14 Javascript
vue 页面加载进度条组件实例
Feb 05 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
Sep 20 Javascript
vue cli4.0项目引入typescript的方法
Jul 17 Javascript
JavaScript中window和document用法详解
Jul 28 Javascript
手把手教你如何编译打包video.js
Dec 09 Javascript
老生常谈js中的MVC
Jul 25 #Javascript
教你5分钟学会用requirejs(必看篇)
Jul 25 #Javascript
浅谈Vue.js 1.x 和 2.x 实例的生命周期
Jul 25 #Javascript
Vue项目中引入外部文件的方法(css、js、less)
Jul 24 #Javascript
基于JavaScript实现百度搜索框效果
Jun 28 #Javascript
深入理解基于vue-cli的vuex配置
Jul 24 #Javascript
JS按条件 serialize() 对应标签的使用方法
Jul 24 #Javascript
You might like
一贴学会PHP 新手入门教程
2009/08/03 PHP
php输出全球各个时区列表的方法
2015/03/31 PHP
PHP导入导出Excel代码
2015/07/07 PHP
双冒号 ::在PHP中的使用情况
2015/11/05 PHP
php基于curl主动推送最新内容给百度收录的方法
2016/10/14 PHP
PHP面向对象学习之parent::关键字
2017/01/18 PHP
基于jquery的商品展示放大镜
2010/08/07 Javascript
Jquery动态更改一张位图的src与Attr的使用
2013/07/31 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
2016/11/11 Javascript
分享bootstrap学习笔记心得(组件及其属性)
2017/01/11 Javascript
jquery表单提交带错误信息提示效果
2017/03/09 Javascript
详解Vue2+Echarts实现多种图表数据可视化Dashboard(附源码)
2017/03/21 Javascript
Vue项目webpack打包部署到服务器的实例详解
2017/07/17 Javascript
详解使用路由延迟加载 Angular 模块
2017/10/12 Javascript
Angular项目从新建、打包到nginx部署全过程记录
2017/12/09 Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
2017/12/31 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
微信小程序绑定手机号获取验证码功能
2019/10/22 Javascript
Python新手在作用域方面经常容易碰到的问题
2015/04/03 Python
Python学习之用pygal画世界地图实例
2017/12/07 Python
浅析python3中的os.path.dirname(__file__)的使用
2018/08/30 Python
Laravel+Dingo/Api 自定义响应的实现
2019/02/17 Python
PyTorch中topk函数的用法详解
2020/01/02 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
关键字final的用法
2013/10/02 面试题
酒店管理专业学生求职信
2013/09/27 职场文书
亮化工程实施方案
2014/03/17 职场文书
初中学生评语大全
2014/04/24 职场文书
2014年留守儿童工作总结
2014/12/10 职场文书
利用Python脚本写端口扫描器socket,python-nmap
2022/07/23 Python