一、React-router V4版本修改内容及一些坑

1、所有组件更改为从react-router-dom导入

1
2
3
4
5
6
7
8
//v2
import {Router,Route,hashHistory} from 'react-router';

// 4.xx写法
//v4
import {Route,BrowserRouter as Router, Switch} from 'react-router-dom';

// 如果搭配redux,你还需要使用react-router-redux

2、将所有替换为

1
2
3
4
5
6
//v2

"/" component={PCIndex}>Route>
"/details/:uniqueky" component={PCNewsDetails}>Route>
"/usercenter" component={PCUserCenter}>Route>
</Router>

现在需要更改为BrowserRouter

  • 这里的代码不仅仅是将Router替换为BrowserRouter,而且还把所有的Route中用Switch包裹起来.
1
2
3
4
5
6
7
8
//v4


"/" component={MobileIndex}>Route>
"/details/:uniqueky" component={MobileNewsDetails}>Route>
"/usercenter" component={MobileUserCenter}>Route>
</Switch>
BrowserRouter>

3、只能有一个子节点

只能有一个子节点,所以官网建议的是使用进行包裹

1
2
3
4
5
6
// v3
'/' component={App}>

'about' component={About} />
'contact' component={Contact} />
</Route>
1
2
3
4
5
6
7
8
// v4
const App = () => (

'/' component={Home} />
'/about' component={About} />
'/contact' component={Contact} />
</Switch>
)

4、最坑的地方:在当前目录下的文件路径不再使用./, 而是直接用/.

在进行文件引用的时候 ,./src/js的写法需要更改文’/src/js‘, 这是更改之后最坑的地方

二、安装

react-router-dom暴露出react-router中暴露的对象与方法,因此你只需要安装并引用react-router-dom即可

1
npm install --save react-router-dom

三、路由器(Router)

在你开始项目前,你需要决定你使用的路由器的类型。对于网页项目,存在两种组件。当存在服务器来管理动态请求时,需要使用组件,而被用于静态网站。通常,我们更倾向选择,但如果你的网站仅用来呈现静态文件,那么将会是一个好选择

四、历史(History)

每个路由器都会创建一个history对象并用其保持追踪当前location[注1]并且在有变化时对网站进行重新渲染。这个history对象保证了React Router提供的其他组件的可用性,所以其他组件必须在router内部渲染。一个React Router组件如果向父级上追溯却找不到router组件,那么这个组件将无法正常工作

五、渲染

路由器组件无法接受两个及以上的子元素。基于这种限制的存在,创建一个组件来渲染应用其余部分是一个有效的方法

1
2
3
4
5
6
import { BrowserRouter } from 'react-router-dom'
Reactdom.render((


</BrowserRouter>
), document.getElementById('root'))

六、

应用通过组件定义。简化一下,我们将应用拆分成两个部分。

组件包含网站的导航链接。
组件则呈现其余内容

1
2
3
4
5
6
const App = () => (



</div>
)

七、路由(Route)

组件是React Router中主要的结构单元。在任意位置只要匹配了URL的路径名(pathname)你就可以创建元素进行渲染

1、路径(Path)

接受一个数为string类型的path,该值路由匹配的路径名的类型。例如:会匹配以/roster开头的路径名。在当前path参数与当前location的路径相匹配时,路由就会开始渲染React元素。若不匹配,路由不会进行任何操作

1
2
3
4
5
6
'/roster'/>
// 当路径名为'/'时, path不匹配
// 当路径名为'/roster'或'/roster/2'时, path匹配
// 当你只想匹配'/roster'时,你需要使用"exact"参数
// 则路由仅匹配'/roster'而不会匹配'/roster/2'
'/roster'/>
  • 注意:在匹配路由时,React Router只关注location的路径名。当URL如下时
1
http://www.example.com/my-projects/one?extra=false
  • React Router去匹配的只是'/my-projects/one'这一部分

2、匹配路径

path-to-regexp包用来决定route元素的path参数与当前location是否匹配。它将路径字符串编译成正则表达式,并与当前location的路径名进行匹配比较

  • 当路由地址匹配成功后,会创建一个含有以下属性的match对象:
    • url :与当前location路径名所匹配部分
    • path:路由的地址
    • isExactpath 是否等于 pathname
    • params:从path-to-regexp获取的路径中取出的值都被包含在这个对象中

使用route tester这款工具来对路由与URL进行检验

3、创建你的路由

可以在路由器(router)组件中的任意位置创建多个,但通常我们会把它们放在同一个位置。使用组件来包裹一组会遍历自身的子元素(即路由)并对第一个匹配当前路径的元素进行渲染

  • 我们希望匹配一下路径
    • /:主页
    • /roster: 团体列表
    • /roster/:number:运动员页面,使用运动员的编号作为标识
    • /schedule:团队的赛程表

为了在应用中能匹配路径,在创建元素时必须带有需要匹配的path作为参数

1
2
3
4
5
6

'/' component={Home}/>
{/* both /roster and /roster/:number begin with /roster */}
'/roster' component={Roster}/>
'/schedule' component={Schedule}/>
</Switch>

4、是如何渲染的?

当一个路由的path匹配成功后,路由用来确定渲染结果的参数有三种。只需要提供其中一个即可

  • component : 一个React组件。当带有component参数的route匹配成功后,route会返回一个新的元素,其为component参数所对应的React组件(使用React.createElement创建)。
  • render : 一个返回React element的函数。当匹配成功后调用该函数。该过程与传入component参数类似,并且对于行级渲染与需要向元素传入额外参数的操作会更有用。
  • children : 一个返回React element的函数。与上述两个参数不同,无论route是否匹配当前location,其都会被渲染
1
2
3
4
5
6
7
8
9
10
'/page' component={Page} />
const extraProps = { color: 'red' }
'/page' render={(props) => (

)}/>
'/page' children={(props) => (
props.match
? <Page {...props}/>
:
)}/>

通常component参数与render参数被更经常地使用。children参数偶尔会被使用,它更常用在path无法匹配时呈现的’空’状态。在本例中并不会有额外的状态,所以我们将使用component参数

  • 通过渲染的元素会被传入一些参数。分别是match对象,当前location对象以及history对象(由router创建)

5、

现在我们清楚了根路由的结构,我们需要实际渲染我们的路由。对于这个应用,我们将会在

组件中渲染,这一过程会将route匹配生成的HTML放在
节点中

1
2
3
4
5
6
7
8
9
10
import { Switch, Route } from 'react-router-dom'
const Main = () => (


'/' component={Home}/>
'/roster' component={Roster}/>
'/schedule' component={Schedule}/>
</Switch>
ain>
)
  • 注意:主页路由包含额外参数。该参数用来保证路由能准确匹配path

6、嵌套路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// v3
import React from "react";
import { render } from "react-dom";
import { Router, Route, IndexRoute, Link, browserHistory } from "react-router";

const PrimaryLayout = props =>
"primary-layout"
>
Our React Router 3 App</header>



  • ">Home


  • ">User



    {props.children}