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 相关文章推荐
纯JavaScript实现的完美渐变弹出层效果代码
Apr 02 Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 Javascript
Javascript 正则表达式实现为数字添加千位分隔符
Mar 10 Javascript
jQuery插件pagination实现分页特效
Apr 12 Javascript
JS实现仿雅虎首页快捷登录入口及导航模块效果
Sep 19 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
Aug 05 Javascript
JavaScript实现选中文字提示新浪微博分享效果
Jun 15 Javascript
js学习心得_一个简单的动画库封装tween.js
Jul 14 Javascript
解决node-sass偶尔安装失败的方法小结
Dec 05 Javascript
Vuex中的State使用介绍
Jan 19 Javascript
详解vue 动态加载并注册组件且通过 render动态创建该组件
May 30 Javascript
vue自定义右键菜单之全局实现
Apr 09 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中配置IIS7实现基本身份验证的方法
2015/09/24 PHP
PHP+Ajax+JS实现多图上传
2016/05/07 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
详解Yaf框架PHPUnit集成测试方法
2017/12/27 PHP
Windows Live的@live.com域名注册漏洞 利用代码
2006/12/27 Javascript
js实现禁止中文输入的方法
2015/01/14 Javascript
不得不分享的JavaScript常用方法函数集(上)
2015/12/23 Javascript
Bootstrap零基础入门教程(三)
2016/07/18 Javascript
JSON中key动态设置及JSON.parse和JSON.stringify()的区别
2016/12/29 Javascript
jQuery Masonry瀑布流插件使用方法详解
2017/01/18 Javascript
jquery动态赋值id与动态取id方法示例
2017/08/21 jQuery
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
js实现购物车功能
2018/06/12 Javascript
深入理解Angularjs 脏值检测
2018/10/12 Javascript
简单了解JavaScript中常见的反模式
2019/06/21 Javascript
微信小程序实现Swiper轮播图效果
2019/11/22 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
Vue 组件复用多次自定义参数操作
2020/07/27 Javascript
JS获取当前时间戳方法解析
2020/08/29 Javascript
如何使用 vue-cli 创建模板项目
2020/11/19 Vue.js
原生JS实现京东查看商品点击放大
2020/12/21 Javascript
[01:08:56]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第一场 2月7日
2021/03/11 DOTA
简介Django框架中可使用的各类缓存
2015/07/23 Python
python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析
2020/03/08 Python
深入浅析css3 border-image边框图像详解
2015/11/24 HTML / CSS
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
香港个人化生活购物网站:Ballyhoo Limited
2016/09/10 全球购物
华为俄罗斯官方网上商城:购买Huawei手机和平板
2017/04/21 全球购物
德国隐形眼镜店:LuckyLens
2018/07/29 全球购物
Kathmandu新西兰官网:新西兰户外运动品牌
2019/07/27 全球购物
俄罗斯家居用品购物网站:Евродом
2020/11/21 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
大型晚会策划方案
2014/02/06 职场文书
诚信考试标语
2014/06/24 职场文书
怒海潜将观后感
2015/06/11 职场文书
礼貌问候语大全
2015/11/10 职场文书