React路由管理之React Router总结


Posted in Javascript onMay 10, 2018

React项目通常都有很多的URL需要管理,最常使用的解决方案就是React Router了,最近学习了一下,主要是看了一下官方的英文文档,加以总结,以备后查。

React Router是做什么的呢,官方的介绍是:

A complete routing library for React,keeps your UI in sync with the URL. It has a simple API with powerful features like lazy code loading, dynamic route matching, and location transition handling built right in. Make the URL your first thought, not an after-thought.

大意即:让UI组件和URL保持同步,通过简单的API即可实现强大的特性如:代码懒加载,动态路由匹配,路径过渡处理等。

下面是一些React Router的用法:

一 简单渲染Route

有一点需要牢记于心,Router 是作为一个React组件,可以进行渲染。

// ...
import { Router, Route, hashHistory } from 'react-router'

render((
 <Router history={hashHistory}>
  <Route path="/" component={App}/>
 </Router>
), document.getElementById('app'))

这里使用了hashHistory - 它管理路由历史与URL的哈希部分。

添加更多的路由,并指定它们对应的组件

import About from './modules/About'
import Repos from './modules/Repos'

render((
 <Router history={hashHistory}>
  <Route path="/" component={App}/>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
 </Router>
), document.getElementById('app'))

二 Link

// modules/App.js
import React from 'react'
import { Link } from 'react-router'

export default React.createClass({
 render() {
  return (
   <div>
    <h1>React Router Tutorial</h1>
    <ul role="nav">
     <li><Link to="/about">About</Link></li>
     <li><Link to="/repos">Repos</Link></li>
    </ul>
   </div>
  )
 }
})

这里使用了Link 组件,它可以渲染出链接并使用 to 属性指向相应的路由。

三 嵌套路由

如果我们想添加一个导航栏,需要存在于每个页面上。如果没有路由器,我们就需要封装一个一个nav组件,并在每一个页面组件都引用和渲染。随着应用程序的增长代码会显得很冗余。React-router则提供了另一种方式来嵌套共享UI组件。

实际上,我们的app都是一系列嵌套的盒子,对应的url也能够说明这种嵌套关系:

<App>    {/* url /     */}
 <Repos>  {/* url /repos   */}
  <Repo/> {/* url /repos/123 */}
 </Repos>
</App>

因此,可以通过把子组件嵌套到 公共组件 App上使得 App组件上的 导航栏 Nav 等公共部分能够共享:

// index.js
// ...
render((
 <Router history={hashHistory}>
  <Route path="/" component={App}>
   {/* 注意这里把两个子组件放在Route里嵌套在了App的Route里/}
   <Route path="/repos" component={Repos}/>
   <Route path="/about" component={About}/>
  </Route>
 </Router>
), document.getElementById('app'))

接下来,在App中将children渲染出来:

// modules/App.js
// ...
 render() {
  return (
   <div>
    <h1>React Router Tutorial</h1>
    <ul role="nav">
     <li><Link to="/about">About</Link></li>
     <li><Link to="/repos">Repos</Link></li>
    </ul>

    {/* 注意这里将子组件渲染出来 */}
    {this.props.children}

   </div>
  )
 }
// ...

四 有效链接

Link组件和a标签的不同点之一就在于Link可以知道其指向的路径是否是一个有效的路由。

<li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>
<li><Link to="/repos" activeStyle={{ color: 'red' }}>Repos</Link></li>

可以使用 activeStyle 指定有效链接的样式,也可以使用activeClassName指定有效链接的样式类。

大多数时候,我们并不需要知道链接是否有效,但在导航中这个特性则十分重要。比如:可以在导航栏中只显示合法的路由链接。

// modules/NavLink.js
import React from 'react'
import { Link } from 'react-router'

export default React.createClass({
 render() {
  return <Link {...this.props} activeClassName="active"/>
 }
})
// modules/App.js
import NavLink from './NavLink'

// ...

<li><NavLink to="/about">About</NavLink></li>
<li><NavLink to="/repos">Repos</NavLink></li>

可以在NavLink中指定只有 .active 的链接才显示,这样如果路由无效,则该链接就不会出现在导航栏中了。

五 URL参数

考虑下面的url:

/repos/reactjs/react-router
/repos/facebook/react

他们可能对应的是这种形式:

/repos/:userName/:repoName

:后面是可变的参数

url中的可变参数可以通过 this.props.params[paramsName] 获取到:

// modules/Repo.js
import React from 'react'

export default React.createClass({
 render() {
  return (
   <div>
{/* 注意这里通过this.props.params.repoName 获取到url中的repoName参数的值 */}
    <h2>{this.props.params.repoName}</h2>
   </div>
  )
 }
})
// index.js
// ...
// import Repo
import Repo from './modules/Repo'

render((
 <Router history={hashHistory}>
  <Route path="/" component={App}>
   <Route path="/repos" component={Repos}/>
   {/* 注意这里的路径 带了 :参数 */}
   <Route path="/repos/:userName/:repoName" component={Repo}/>
   <Route path="/about" component={About}/>
  </Route>
 </Router>
), document.getElementById('app'))

接下来访问 /repos/reactjs/react-router 和 /repos/facebook/react 就会看到不同的内容了。

六 默认路由

// index.js
import { Router, Route, hashHistory, IndexRoute } from 'react-router'
// and the Home component
import Home from './modules/Home'

// ...

render((
 <Router history={hashHistory}>
  <Route path="/" component={App}>

   {/* 注意这里* /}
   <IndexRoute component={Home}/>

   <Route path="/repos" component={Repos}>
    <Route path="/repos/:userName/:repoName" component={Repo}/>
   </Route>
   <Route path="/about" component={About}/>
  </Route>
 </Router>
), document.getElementById('app'))

这里添加了IndexRoute来指定默认的路径 / 所对应的组件。注意它没有path属性值。

同理也有 默认链接组件 IndexLink。、

七 使用Browser History

前面的例子一直使用的是hashHistory,因为它一直可以运行,但更好的方式是使用Browser History,它可以不依赖哈希端口 (#)。

首先需要改 index.js:

// ...
// bring in `browserHistory` instead of `hashHistory`
import { Router, Route, browserHistory, IndexRoute } from 'react-router'

render((
{/* 注意这里 */}
 <Router history={browserHistory}>
  {/* ... */}
 </Router>
), document.getElementById('app'))

其次需要 修改webpack的本地服务配置,打开 package.json 添加 ?history-api-fallback :

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

最后需要在 index.html中 将文件的路径改为相对路径:

<!-- index.html -->
<!-- index.css 改为 /index.css -->
<link rel="stylesheet" href="/index.css" rel="external nofollow" >

<!-- bundle.js 改为 /bundle.js -->
<script src="/bundle.js"></script>

这样就去掉了url中的 # 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用tip解决Ext列宽度不够的问题
Dec 13 Javascript
js实现获取焦点后光标在字符串后
Sep 17 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
Sep 28 Javascript
Select下拉框模糊查询功能实现代码
Jul 22 Javascript
浅谈JavaScript的闭包函数
Dec 08 Javascript
微信小程序 template模板详解及实例
Feb 21 Javascript
JavaScript实现的搜索及高亮显示功能示例
Aug 14 Javascript
vue项目设置scrollTop不起作用(总结)
Dec 21 Javascript
js前端如何写一个精确的倒计时代码
Oct 25 Javascript
js中关于Blob对象的介绍与使用
Nov 29 Javascript
JQuery绑定事件四种实现方法解析
Dec 02 jQuery
vue+echarts实现中国地图流动效果(步骤详解)
Jan 27 Vue.js
React从react-router路由上做登陆验证控制的方法
May 10 #Javascript
详解Angular路由之路由守卫
May 10 #Javascript
JavaScript实现一个简易的计算器实例代码
May 10 #Javascript
浅谈node.js 命令行工具(cli)
May 10 #Javascript
Js经典案例的实例代码
May 10 #Javascript
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
May 10 #Javascript
vuex与组件联合使用的方法
May 10 #Javascript
You might like
PHP swfupload图片上传的实例代码
2013/09/30 PHP
codeigniter框架The URI you submitted has disallowed characters错误解决方法
2014/05/06 PHP
在Mac OS上搭建PHP的Yii框架及相关测试环境
2016/02/14 PHP
[原创]smarty简单模板变量输出方法
2016/07/09 PHP
修改yii2.0用户登录使用的user表为其它的表实现方法(推荐)
2017/08/01 PHP
RR vs IO BO3 第一场2.13
2021/03/10 DOTA
Firefox div高度自适应
2009/04/28 Javascript
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
2010/09/12 Javascript
jQuery ajax dataType值为text json探索分享
2013/09/23 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
window resize和scroll事件的基本优化思路
2014/04/29 Javascript
让angularjs支持浏览器自动填表
2014/11/10 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
2020/09/13 Javascript
详解jquery事件delegate()的使用方法
2016/01/25 Javascript
详解JavaScript中Hash Map映射结构的实现
2016/05/21 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
2016/12/26 Javascript
Node.js websocket使用socket.io库实现实时聊天室
2017/02/20 Javascript
浅谈Postman解决token传参的问题
2018/03/31 Javascript
用ES6写全屏滚动插件的示例代码
2018/05/02 Javascript
Bootstrap table中toolbar新增条件查询及refresh参数使用方法
2018/05/18 Javascript
jQuery中each遍历的三种方法实例分析
2018/09/07 jQuery
利用Python如何生成hash值示例详解
2017/12/20 Python
初探TensorFLow从文件读取图片的四种方式
2018/02/06 Python
Python爬取商家联系电话以及各种数据的方法
2018/11/10 Python
Python使用configparser库读取配置文件
2020/02/22 Python
python中threading开启关闭线程操作
2020/05/02 Python
python def 定义函数,调用函数方式
2020/06/02 Python
Html5调用手机摄像头并实现人脸识别的实现
2018/12/21 HTML / CSS
应届毕业生求职信范例分享
2013/12/17 职场文书
水毁工程实施方案
2014/04/01 职场文书
《孔繁森》教学反思
2014/04/17 职场文书
男性健康日的活动方案
2014/08/18 职场文书
2014年银行信贷员工作总结
2014/12/08 职场文书
导游词之上海杜莎夫人蜡像馆
2019/11/22 职场文书
Python+tkinter实现高清图片保存
2022/03/13 Python