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 相关文章推荐
你的编程语言可以这样做吗?
Sep 07 Javascript
Javascript 布尔型分析
Dec 22 Javascript
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 Javascript
向当前style sheet中插入一个新的style实现方法
Apr 01 Javascript
给Flash加一个超链接(推荐使用透明层)兼容主流浏览器
Jun 09 Javascript
flash遮住div问题的正确解决方法
Feb 27 Javascript
js使用循环清空某个div中的input标签值
Sep 29 Javascript
html的DOM中Event对象onblur事件用法实例
Jan 21 Javascript
js检测iframe是否加载完成的方法
Nov 26 Javascript
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
Feb 09 Javascript
浅谈Node异步编程的机制
Oct 18 Javascript
微信小程序之数据绑定原理解析
Aug 14 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+MYSQL会员系统的登陆即权限判断实现代码
2011/09/23 PHP
php实现文件下载代码分享
2014/08/19 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
比较详细的关于javascript中void(0)的具体含义解释
2007/08/02 Javascript
Javascript计算时间差的函数分享
2011/07/04 Javascript
javascript特殊用法示例介绍
2013/11/29 Javascript
Javascript Object 对象学习笔记
2014/12/17 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
JavaScript随机生成颜色的方法
2016/10/15 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
js以及jquery实现手风琴效果
2020/04/17 Javascript
js实现百度登录框鼠标拖拽效果
2017/03/07 Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
2017/07/11 Javascript
JS实现去除数组中重复json的方法示例
2017/12/21 Javascript
vue实现中部导航栏布局功能
2019/07/30 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
Zabbix实现微信报警功能
2016/10/09 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
PYTHON EVAL的用法及注意事项解析
2019/09/06 Python
python中栈的原理及实现方法示例
2019/11/27 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
2020/04/01 Python
详解用selenium来下载小姐姐图片并保存
2021/01/26 Python
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
HTML5 window/iframe跨域传递消息 API介绍
2013/08/26 HTML / CSS
HTML5 Video/Audio播放本地文件示例介绍
2013/11/18 HTML / CSS
美国领先的眼镜和太阳镜在线零售商:Glasses.com
2019/08/26 全球购物
网络工程师的自我评价
2013/10/02 职场文书
个人找工作的自我评价
2013/10/17 职场文书
《骆驼和羊》教学反思
2014/02/27 职场文书
毕业实习证明(4篇)
2014/10/28 职场文书
小学生读书笔记范文
2015/06/30 职场文书
会议室使用管理制度
2015/08/06 职场文书
解析:创业计划书和商业计划书二者之间到底有什么区别
2019/08/14 职场文书
nginx常用命令放入shell脚本详解
2021/03/31 Servers
win10电脑关机快捷键是哪个 win10快速关机的几种方法
2022/08/14 数码科技