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 相关文章推荐
HTML中不支持静态Expando的元素的问题
Mar 08 Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
Oct 11 Javascript
jQuery获取Select选择的Text和Value(详细汇总)
Jan 25 Javascript
jquery中object对象循环遍历的方法
Dec 18 Javascript
jquery PrintArea 实现票据的套打功能(代码)
Mar 17 Javascript
AngularJS中重新加载当前路由页面的方法
Mar 09 Javascript
vue文件树组件使用详解
Mar 29 Javascript
JS实现二维数组元素的排列组合运算简单示例
Jan 28 Javascript
详解JavaScript栈内存与堆内存
Apr 04 Javascript
js实现秒表计时器
Dec 16 Javascript
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 Javascript
Vue 实现拨打电话操作
Nov 16 Javascript
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动态图像的创建
2006/10/09 PHP
PHP邮件专题
2006/10/09 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
详解php中反射的应用
2016/03/15 PHP
thinkphp配置文件路径的实现方法
2016/08/30 PHP
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
利用javascript中的call实现继承
2007/01/22 Javascript
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
关于Jqzoom的使用心得 jquery放大镜效果插件
2010/04/12 Javascript
js对象数组按属性快速排序
2011/01/31 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
javascript实现table表格隔行变色的方法
2015/05/13 Javascript
自动完成的搜索框javascript实现
2016/02/26 Javascript
jQuery实现手机自定义弹出输入框
2016/06/13 Javascript
Ext JS 实现建议词模糊动态搜索功能
2017/05/13 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
2017/06/15 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
vue内置指令详解
2018/04/03 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
JS数组方法reverse()用法实例分析
2020/01/18 Javascript
[02:21]2018完美盛典章节片——初心
2018/12/17 DOTA
python用模块zlib压缩与解压字符串和文件的方法
2016/12/16 Python
python基础练习之几个简单的游戏
2017/11/10 Python
OpenCV+python手势识别框架和实例讲解
2018/08/03 Python
Django命名URL和反向解析URL实现解析
2019/08/09 Python
TensorFlow2.0:张量的合并与分割实例
2020/01/19 Python
Python面向对象程序设计之私有变量,私有方法原理与用法分析
2020/03/23 Python
新手学习Python2和Python3中print不同的用法
2020/06/09 Python
迪奥官网:Dior.com
2018/12/04 全球购物
static关键字的用法
2013/10/07 面试题
小学生爱国演讲稿
2014/04/25 职场文书
汽车专业求职信
2014/06/05 职场文书
关于redisson缓存序列化几枚大坑说明
2021/08/04 Redis
Python序列化模块JSON与Pickle
2022/06/05 Python