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 相关文章推荐
学习YUI.Ext 第六天--关于树TreePanel(Part 2异步获取节点)
Mar 10 Javascript
javascript 新浪背投广告实现代码
Jul 07 Javascript
jquery获取被勾选的checked(选中)的那一行的3列和4列的值
Jul 04 Javascript
JavaScript调试技巧之console.log()详解
Mar 19 Javascript
理解js回收机制通俗易懂版
Feb 29 Javascript
Vue表单验证插件的制作过程
Apr 01 Javascript
JS判断微信扫码的方法
Aug 07 Javascript
使用socket.io制做简易WEB聊天室
Jan 02 Javascript
vue router+vuex实现首页登录验证判断逻辑
May 17 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
Sep 20 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
Sep 28 Javascript
jQuery+PHP+Ajax实现动态数字统计展示功能
Dec 25 jQuery
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
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
php ftp文件上传函数(基础版)
2010/06/03 PHP
php下正则来匹配dede模板标签的代码
2010/08/21 PHP
apache php模块整合操作指南
2012/11/16 PHP
PHP实现把数字ID转字母ID
2013/08/12 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
2014/06/12 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
phpcms实现验证码替换及phpcms实现全站搜索功能教程详解
2017/12/13 PHP
laravel中短信发送验证码的实现方法
2018/04/25 PHP
动态载入/删除/更新外部 JavaScript/Css 文件的代码
2010/07/03 Javascript
firefox火狐浏览器与与ie兼容的2个问题总结
2010/07/20 Javascript
19个很有用的 JavaScript库推荐
2011/06/27 Javascript
js禁止document element对象选中文本实现代码
2013/03/21 Javascript
Node.js的特点和应用场景介绍
2014/11/04 Javascript
jQuery中removeClass()方法用法实例
2015/01/05 Javascript
jquery实现鼠标滑过小图时显示大图的方法
2015/01/14 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
vue通过cookie获取用户登录信息的思路详解
2018/10/30 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
python通过线程实现定时器timer的方法
2015/03/16 Python
Python selenium实现微博自动登录的示例代码
2018/05/16 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
python3解析库BeautifulSoup4的安装配置与基本用法
2018/06/26 Python
Linux下python制作名片示例
2018/07/20 Python
python中scikit-learn机器代码实例
2018/08/05 Python
python高效过滤出文件夹下指定文件名结尾的文件实例
2018/10/21 Python
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
2020/10/09 Python
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
CAT鞋加拿大官网:CAT Footwear加拿大
2020/08/05 全球购物
体育教育专业毕业生自荐信
2013/11/15 职场文书
医生进修自我鉴定
2014/01/19 职场文书
公司投资建议书
2014/05/16 职场文书
组工干部对照检查材料
2014/08/25 职场文书
首席执行官观后感
2015/06/03 职场文书
童年读书笔记
2015/06/26 职场文书