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 相关文章推荐
关于UTF-8的客户端用AJAX方式获取GB2312的服务器端乱码问题的解决办法
Nov 30 Javascript
JavaScript中的console.dir()函数介绍
Dec 29 Javascript
详细解密jsonp跨域请求
Apr 15 Javascript
JS使用parseInt解析数字实现求和的方法
Aug 05 Javascript
jquery自定义右键菜单、全选、不连续选择
Mar 01 Javascript
详解javascript跨浏览器事件处理程序
Mar 27 Javascript
js 定义对象数组(结合)多维数组方法
Jul 27 Javascript
Bootstrap3 多选和单选框(checkbox)
Dec 29 Javascript
基于jQuery实现的Ajax 验证用户名唯一性实例代码
Jun 28 jQuery
JQuery EasyUI的一些常用组件
Jul 12 jQuery
利用Vue实现一个markdown编辑器实例代码
May 19 Javascript
Django+Vue实现WebSocket连接的示例代码
May 28 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工具型代码之印章抠图
2018/07/18 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
2019/02/08 PHP
PHP实现提取多维数组指定一列的方法总结
2019/12/04 PHP
Laravel6.18.19如何优雅的切换发件账户
2020/06/14 PHP
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
jQuery基本过滤选择器使用介绍
2013/04/18 Javascript
JS:window.onload的使用介绍
2013/11/13 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
2015/01/02 Javascript
JQuery插件ajaxfileupload.js异步上传文件实例
2015/05/19 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
2015/09/12 Javascript
基于BootStrap Metronic开发框架经验小结【九】实现Web页面内容的打印预览和保存操作
2016/05/12 Javascript
老生常谈js动态添加事件--- 事件委托
2016/07/19 Javascript
JS图片放大效果简单实现代码
2016/09/08 Javascript
微信小程序 开发经验整理
2017/02/15 Javascript
实现微信小程序的wxml文件和wxss文件在webstrom的支持
2017/06/12 Javascript
详解使用PM2管理nodejs进程
2017/10/24 NodeJs
vue-cli构建项目下使用微信分享功能
2018/05/28 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
2018/12/03 Javascript
解决layui 三级联动下拉框更新时回显的问题
2019/09/03 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
Python中的变量和作用域详解
2016/07/13 Python
使用python遍历指定城市的一周气温
2017/03/31 Python
python 魔法函数实例及解析
2019/09/25 Python
Python3.7 pyodbc完美配置访问access数据库
2019/10/03 Python
python如何保存文本文件
2020/06/07 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
2020/12/07 Python
Yahoo-PHP面试题3
2012/01/14 面试题
暑期社会实践学生的自我评价
2014/01/09 职场文书
农业开发项目建议书
2014/05/16 职场文书
作弊检讨书范文
2015/05/06 职场文书
Nginx+Tomcat负载均衡集群的实现示例
2021/10/24 Servers
SpringBoot整合minio快速入门教程(代码示例)
2022/04/03 Java/Android
Java存储没有重复元素的数组
2022/04/29 Java/Android