项目目前用的React Router版本是 V5

快速开始

  • 首先,安装create-react-app并用它创建一个新的项目
1
2
3
npm install -g create-react-app
create-react-app demo-app
cd demo-app
  • yarn 安装 React Router
    yarn add react-router-dom@5.3.0

主要组件

React Router中的组件主要分为三类:

  • 路由器: 例如BrowserRouterHashRouter
  • 路由匹配器: 例如RouteSwitch
  • 导航: 例如Link, NavLink, Redirect

简单例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// React 应用中的 App.js 文件

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './views/home'

class App extends React.Component {
render() {
return (
<BrowserRouter>
<Route path="/home" component={Home} />
</BrowserRouter>
);
}
}

export default App;

路由器

每个React Router应用程序的核心应该是路由器组件,对于web项目,react-router-dom提供BrowserRouter和HashRouter路由器

  1. 底层原理不一样:
  • BrowserRouter使用的是H5的history API,不兼容IE9及以下版木
  • HashRouter使用的是URL的哈希值
  1. path表现形式不一样
  • BrowserRouter的路径中没有#,例如:localhost:3000/home/
  • HashRouter的路径包含#,例如: localhost:3000/#/home/
  1. 刷新后对路由state參数的影啊
  • BrowserRouter没有任何影啊,因为state保存在history对象中
  • HashRouter刷新后会导致路由state参数的丢失
  1. 备注:HashRouter可以用于解决一此路径错误相关的问题

路由匹配器

两种路由匹配组件:SwitchRoute
当渲染Switch组件时,将搜索它的Route子元素,查找路径与当前URL匹配的元素,呈现找到的第一个Route并忽略其他路由

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
34
35
36
37
38
39
40
41
42
43
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";

function App() {
return (
<div>
<Switch>
{/* 如果当前URL是/home,则呈现此路由而其余的被忽略 */}
<Route path="/home">
<About />
</Route>

{/* 请注意这两个路由的顺序。更具体的path ="/contact/:id"在path ="/contact"之前,因此查看单个联系人时,这个路线将被渲染 */}
<Route path="/contact/:id">
<Contact />
</Route>
<Route path="/contact">
<AllContacts />
</Route>

{/*
如果先前的路线都不提供任何东西,这条路线充当后备路线。
重要提示:路径为'/'的路线将始终匹配URL,这就是为什么我们把它放在最后。
*/}
<Route path="/">
<Home />
</Route>
</Switch>
</div>
);
}

ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);

需要注意的一点是Route path匹配的是URL的开头而不是整个URL,所以会始终与URL匹配。
所以我们通常将这个Route放在的最后
还有一个解决方案就是使用exact,精准匹配

导航

React Router提供了一个Link组件来在您的应用程序中创建链接

1
<Link to="/">Home</Link>

NavLink是的一种特殊类型,当其prop与当前位置匹配时,可以给它设置一个activeClassName的样式。

1
<NavLink to="/react" activeClassName="hurray">React</NavLink>

Redirect是强制导航

1
<Redirect to="/login" />

路由组件和一般组件

  1. 写法不同:
    • 一般组件: <Home/>
    • 路由组件: <Route path="/home" component={Home}/›
  2. 存放位置不同:
    • 一般组件: components
    • 路由组件: pages
  3. 收到的props不同:
    • 一般组件: 写组件标签传递什么参数就收到什么参数
    • 路由组件: 接收三个固定属性
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      history:
      go: f go (n)
      goBack: f goBack()
      goForward: f goForward()
      push: f push(path, state)
      replace: f replace (path, state)
      location:
      pathname: "/home"
      search: ""
      state: undefined
      match:
      params: {}
      path: "/home"
      url: "/home"

路由组件动态传参

  1. params参数
  • 路由链接(携带参数): <Link to="/demo/test/tom/18">详情</Link>
  • 注册路由(声明接收): <Route path="/demo/test/:name/:age" component={Test}/>
  • 按收参数: this.props.match.params
  1. search参数
  • 路由链接(携带参数): <Link to=' /demo/test?name=tom&age=18'}>详情</Link>
  • 注册路由(无需声明,正常注册即可): <Route path="/demo/test" component={Test}/>
  • 接收参数: this.props.location.search
  • 备注:获收到的search是urlencoded编码字待串,需要借助querystring解析
  1. state参数
  • 路由链接(携带参数):
    1
    <Link to={{path:'/demo/test',state: {name:"tom',age:181}}}>详情</Link>
  • 注册路由(无需声明,正常注册即可): <Route path="/demo/test" component={Test}/>
  • 接收参数: this.props.location.state
  • 备注: 刷新也可以保留佳参数

编程式路由导航

借助this.props.history对象上的API操作路由跳转、前进、后退

  • this.props.history.push()
  • this.props.history.replace()
  • this.props.history.goBack()
  • this.props.history.goForward()
  • this.props.history.go()