React路由


title: React 路由 date: 2020-05-10 13:59:49

tags: React

安装 react-router-dom

可以使用<Link>,<NavLink>标签

1
npm install react-router-dom --save

创建路由模式

  1. hash 模式
  2. history 模式
1
2
3
4
//hash模式
import { BrowserRouter as Router, Link, Route } from "react-router-dom";
//history模式
import { Link, Route, HashRouter as Router } from "react-router-dom";

as类似于起别名,方便简化名称.

创建路由

需要通过使Route进行对组件的声明配置,才能被Link找到.

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
44
45
46
47
48
import React from "react";
// histoty
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
// hash
// import { Link, Route, HashRouter as Router } from 'react-router-dom';

function Page1() {
return <h1>我是Page1</h1>;
}

function Page2() {
return <h1>我是Page2</h1>;
}

function Page3() {
return <h1>我是Page3</h1>;
}

class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}

render() {
return (
<div className="App">
<Router>
<ul>
<li>
<Link to="page1">Page1</Link>
</li>
<li>
<Link to="page2">Page2</Link>
</li>
<li>
<Link to="page3">Page3</Link>
</li>
</ul>
<Route exact path="/page1" component={Page1}></Route>
<Route exact path="/page2" component={Page2}></Route>
<Route exact path="/page3" component={Page3}></Route>
</Router>
</div>
);
}
}
export default App;

函数式(带组件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//router.js
import React from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import Login from "./pages/login";
import Home from "./pages/home";
import App from "./pages/app";

//函数式
export default function ARouter() {
return (
<Router>
<Switch>
<Route exact path="/" component={App}></Route>
<Route path="/home" component={Home}></Route>
<Route path="/login" component={Login}></Route>
</Switch>
</Router>
);
}
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
import React from "react";

import { Link } from "react-router-dom";

function App() {
return (
<div className="App">
<Link to="/home">去首页</Link>
<Link to="/login">去登陆</Link>
</div>
);
}

//有状态组件点击跳转
class App extends React.Component {
handleJump = () => {
this.props.histroy.push("/login");
};
render() {
return (
<div className="container">
<Link to="/login"></Link>
<Link to="/home"></Link>
<Button onClick={handleJump}>点击去登陆</Button>
</div>
);
}
}

export default App;

如果用Switch,浏览器输入/home也只会加载 App 页,因为/home先匹配了/

加上 exact 可以精准匹配

如果导入的是HashRouter,会自动加上#http://localhost:3000/login#/

手动跳转

当你使用 History 路由的时候,某些时候需要主动的跳转道某个路由,

这时又不能去触发节点行为,所以这个时候就可以通过 API 的方式,进行跳转.

1
2
3
4
5
6
// 跳转页面
this.props.history.push(参数和to的内容相似);
this.props.history.push("page1");

// 重定向页面
this.props.history.replace("page2");

当然还有 hash 的 go 方法。

动态路由

路由传值

路由传参(传值)一般使用paramsquery.

通过给to传递一个对象的方式进行数据传递.

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
<div className="App">
<Router>
<ul>
<li>
<Link
to={{
pathname: "/page1/10",
search: "?roles=[10, 20]",
state: { name: "Tom" },
}}
>
Page1
</Link>
</li>
<li>
<Link to="page2">Page2</Link>
</li>
<li>
<Link to="page3">Page3</Link>
</li>
</ul>
<Route exact path="/page1/:id" component={Page1}></Route>
<Route exact path="/page2" component={Page2}></Route>
<Route exact path="/page3" component={Page3}></Route>
</Router>
</div>

可以看到,向page1的路由上添加了一个:id表示需要传递paramid的值,

同时声明了search的文本和state对象多种方式传递了参数。以便根据不同的场景使用。

路由 Hooks

useParams: 获取参数(内部封装)

如果在有状态组件(也就是 class 声明的类中)获取参数,需要通过this.props.match.parmas.id.

而在函数式组件(无状态组件)中获取,需要通过useParams()

useHistory: 通过 JS Api 操作路由跳转

函数式组件没有作用域,this 为 undefined.所以需要使用 useHistory 进行跳转.

如果在有状态组件中,需要this.props.history.push('/')进行跳转.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Detail() {
const params = useParams();
const history = useHistory();
return (
<div>
<p>当前的参数值为: {params.goodId}</p>
<button
onClick={() => {
history.push("/");
}}
>
跳转
</button>
</div>
);
}