(注:参考自官方英文文档V3.X版本)

react-router是伴随着react框架出现的路由系统,它也是公认的一种优秀的路由解决方案。在使用react-router时候,我们常常会使用其自带的路径跳转组件Link,通过<Link  to="path"></Link>实现跳转,这和传统的<a href="path"></a>何其相似!但它们到底有什么具体的区别呢?

对比<a>,Link组件避免了不必要的重渲染

A  -- 通过<a>标签实现页面跳转:(图中的例子将会在下面详细解答)


----->----->


B --通过<Link>组件实现页面跳转:


  ------>


react-router:只更新变化的部分从而减少DOM性能消耗

react的创新之处在于,它利用虚拟DOM的概念和diff算法实现了对页面的"按需更新",react-router很好地继承了这一点,譬如上图所示,导航组件和三个Tab组件(通过...,通过...,通过...)的重渲染是我们不希望看到的,因为无论跳转到页面一或是页面二,它只需要渲染一次就够了。<Link>组件帮助我们实现了这个愿望,反观<a>标签,每次跳转都重渲染了导航组件和Tab组件试想一下,在一个浩大的项目里,这多么可怕!我们的"渲染"做了许多"无用功",而且消耗了大量弥足珍贵的DOM性能!

react-router的使用

1用npm安装依赖:通过终端进入项目目录里,写入npm install react-router安装react-router;

2从react-router的包里导入自带的组件如Router,Route等,一个简单的路由组件是这样的:

import React from 'react';
import { Router, Route, browserHistory} from 'react-router'
ReactDOM.render(
    <Router history={browserHistory}>
              <Route path='/' component={App}>
                  <Route path='pageOne/:id' component={PageOne}/>
                  <Route path='pageTwo/:id' component={PageTwo} />
              </Route>
     </Router>,
  document.getElementById('root')
);

其中App和PageOne,PageTwo是已定义的react组件

react-router的两大组件--Router和Route

1.Router组件

Router组件是react-router的基础组件,它位于最外层,作用是使UI和URL保持同步,要实现这一点需要向Router组件写入history属性值,Router的history属性有两个值:browserHistory和hashHistory(注:这两个值也是从react-router包中导入的)

  • browserHistory和hashHistory的区别?

        更改路由的方式不同

     1.browserHistory 使用的是 HTML5 的 pushState API来修改浏览器的历史记录

     2.hashHistory 是通过改变地址后面的 hash(也就是URL中#后面的值) 来改变浏览器的历史记录。

        两种方式的特点

1.History API 提供了 pushState() 和 replaceState() 方法来增加或替换历史记录。

而 hash 没有相应的方法,所以browserHistory有替换历史记录的功能,hashHistory没有

2hashHistory实现简单,不需要做额外的服务端改造

2.Route组件

Route组件的Props对象中包含有path和component两个属性。根据当前URL和path属性的比对,Route组件配合其他的Route组件将包裹的子组件映射成完整的组件树

  •   path属性:URL的路径,且子Route的path将与父Route的path组合起来,例如:
<Route path='/' component={Father}>
    <Route path='son' component={Son}>
</Route>

包裹Son组件的Route和包裹Father的Route是父Route和子Route的关系,所以子Route对应的URL为'/'+'son'='/son'

  • path的路径匹配语法:

:paramName -->匹配一段位于 /? 或 # 之后的 URL

()-->匹配可选字段

* -->匹配任意字段

       <Route path="/hello/:name">         // 匹配 /hello/michael 和 /hello/ryan
       <Route path="/hello(/:name)">       // 匹配 /hello, /hello/michael 和 /hello/ryan
       <Route path="/files/*.*">           // 匹配 /files/hello.jpg 和 /file/path/to/hello.jpg
  • component属性:

当匹配到 URL 时,单个的组件会被渲染。它可以 被父 route 组件的 this.props.children 渲染。

  • Route组件将以下属性通过props注入component组件中

children属性:子Route所包裹的component

params属性:URL的动态字段

location:当前的location对象

router属性:一个对象,包含有与路由跳转有关的方法如push(url),repalce(url),go(n),goBack(),goForward()等等

(下文提及)

所以,Route包裹的组件可通过props.chidren,props.params的方式去引用这些属性

React-router的静态跳转和动态跳转

  • 静态跳转 --通过<Link>组件实现静态跳转(文章开头demo的代码)

import React from 'react';
import { Router, Route, browserHistory,Link} from 'react-router'
import ReactDOM from 'react-dom'; class App extends React.Component{ render(){ return (<div> <h1>导航</h1> <a href='/pageOne/:id'>通过a标签跳转到页面一</a> <br/> <Link to='/pageOne/:id'>通过Link组件跳转到页面一</Link> <br/> <Link to='/pageTwo/:id'>通过Link组件跳转到页面二</Link> {this.props.children} </div>) } } const PageOne = (props) => { return (<div> <h1>页面一</h1> </div>) } const PageTwo = (props) => { return (<div> <h1>页面二</h1> </div>) } ReactDOM.render( <Router history={browserHistory}> <Route path='/' component={App}> <Route path='pageOne/:id' component={PageOne}/> <Route path='pageTwo/:id' component={PageTwo} /> </Route> </Router>, document.getElementById('root') )

demo:


-------->


  • 动态跳转 --通过Route注入component中的route属性实现动态跳转

上面我们通过Link组件实现了路径的跳转,但这种方式也有一定的局限性。

第一,它是静态的,也就是必须以写入组件的方式实现跳转;

第二,它没办法提供"时光旅行"的功能,比如:跳到历史记录中的前一个界面,后一个界面,前N个界面,后N个界面,

等等

那么,我们能不能通过调用一个方法的方式去动态地实现路径跳转呢?上文提到的从Route组件中传入component中的

router属性对象解决了这个问题:

  • router.push('url') -->跳到URL为url的页面
  • router.goBack()   -->返回上一个页面
  • router.goForward() --> 去往历史记录中的下一个页面
  • router.go(n): -->n为正数表示向前跳跃,n为负数表示向后跳跃

下面我们基于第一个例子实现这样一个功能,当在从导航跳转到页面一的时候,通过点击按钮调用函数router.push('/')跳回初始的导航页面

import React from 'react';
import { Router, Route, browserHistory,Link} from 'react-router'
import ReactDOM from 'react-dom';
class App extends React.Component{
  render(){
    return (<div>
              <h1>导航</h1>
              <a href='/pageOne/:id'>通过a标签跳转到页面一</a>
              <br/>
              <Link to='/pageOne/:id'>通过Link组件跳转到页面一</Link>
              <br/>
             <Link to='/pageTwo/:id'>通过Link组件跳转到页面二</Link>
              {this.props.children}
            </div>)
  }
}
const PageOne = (props) => {
  console.log(props.router)
  return (<div>
            <h1>页面一</h1>
            <button onClick={() => {
              props.router.push('/')
            }} style={{backgroundColor:'red'}}>
                 跳转到导航页面
            </button>
          </div>)
}
const PageTwo = (props) => {
  return (<div>
            <h1>页面二</h1>
          </div>)
}
ReactDOM.render(
           <Router history={browserHistory}>
              <Route path='/' component={App}>
                  <Route path='pageOne/:id' component={PageOne}/>
                  <Route path='pageTwo/:id' component={PageTwo} />
              </Route>
            </Router>,
document.getElementById('root')
       )

demo如下:


     ---->


React-router官方英文文档地址:

https://github.com/ReactTraining/react-router/tree/v3/docs

React-router官方中文文档地址:

https://react-guide.github.io/react-router-cn/index.html

(注意!英文为Version3版本,与暂处于Version2的中文文档有一定差别,注意区分)

【react-router】从Link组件和a标签的区别说起,react-router如何实现导航并优化DOM性能?的更多相关文章

  1. [React Router v4] Use the React Router v4 Link Component for Navigation Between Routes

    If you’ve created several Routes within your application, you will also want to be able to navigate ...

  2. React和Vue的组件更新比较

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "Helvetica Neue"; color: #404040 } p. ...

  3. 翻译 | 玩转 React 表单 —— 受控组件详解

    原文地址:React.js Forms: Controlled Components 原文作者:Loren Stewart 译者:小 B0Y 校对者:珂珂君 本文涵盖以下受控组件: 文本输入框 数字输 ...

  4. React中的通讯组件

    1.父传子:     传递:当子组件在父组件中当做标签使用的时候,给当前子组件绑定一个自定义属性,值为需要传递的数据     接收:在子组件内部通过this.props进行接收 2.子传父     传 ...

  5. reactjs-swiper react轮播图组件基于swiper

    react轮播图组件基于swiper demo地址:http://reactjs-ui.github.io/reactjs-swiper/simple.html 1. 下载安装 npm install ...

  6. 我们一起来详细的了解react的语法以及组件的使用方法

    jsx的介绍 React 使用 JSX 来替代常规的 JavaScript. JSX 是一个看起来很像 XML 的 JavaScript 语法扩展. jsx的优点 JSX 执行更快,因为它在编译为 J ...

  7. Vue之单文件组件的数据传递,axios请求数据及路由router

    1.传递数据 例如,我们希望把父组件的数据传递给子组件. 可以通过props属性来进行传递. 传递数据三个步骤: 步骤1:在父组件中,调用子组件的组名处,使用属性值的方式往下传递数据 <Menu ...

  8. React Native 学习-组件说明和生命周期

    组件的详细说明(Component Specifications) 当通过调用 React.createClass() 来创建组件的时候,你应该提供一个包含 render 方法的对象,并且也可以包含其 ...

  9. React:快速上手(2)——组件通信

    React:快速上手(2)——组件通信 向父组件传递数据 父组件可以通过设置子组件的props属性进行向子组件传值,同时也可以传递一个回调函数,来获取到子组件内部的数据. 效果演示 子组件是输入框,父 ...

随机推荐

  1. 对JavaScript中this的理解

    JavaScript中的this其实没传说中的那么难,也没那么乱. 我们来分析下,this主要是跟它的执行环境有关. 而通常情况下,this都是放在函数体中或可执行的JS代码中(函数体除外). 至于J ...

  2. 网络攻击技术开篇——SQL Injection

    本文转自: http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库 ...

  3. 学习笔记--jQuery基础

    学习笔记也算总结知识点,有些示例可能没有具体到元素,直接给出的语法.大家有基本理解在看可能会好些. jQuery使用前提,需要安装jQuery库 jQuery 库是一个 JavaScript 文件,您 ...

  4. SpringMVC总结的部分教程及使用方法

    注:本文只用注解来实现 SpringMVC各种流程图流程图(其他的各种流程图)jsp.xml.action彼此之间的关系,都如何使用spring-mvc.xml如何配置,放在哪里?action中如何转 ...

  5. system, fileExist函数包装

    #include "stdio.h" #include <string> #include<sys/types.h> #include<fcntl.h ...

  6. Angular.js之服务与自定义服务学习笔记

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Spring IoC介绍与Bean的使用

    1. 介绍 IoC   IoC-Inversion of Control,即"控制反转",它不是什么技术,而是一种设计思想.在 Java 开发中, IoC意味着将设计好的对象交给容 ...

  8. FineUIMvc随笔 - 怎样在控件中嵌套 HTML

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户需求 有网友在<FineUI总群1>问这么一个问题:怎么把 HTML 嵌套在控件中? 这是很多刚学习 FineU ...

  9. 翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2

    翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2 原文地址:http://onehungrymind.com/build-better-angular-2-application- ...

  10. 免费ERP之云实施

    近日,普实渠道在AIO5软件免费一周年之际,推出了重磅的动作:启动AIO5云实施,推广小微企业免费ERP落地应用. 这无疑是推动客户免费应用ERP的重大里程碑. 当前,在中国小微企业信息化方面,应用情 ...