为什么需要路由
1.单页应用需要进行页面切换
2.通过URL可以定位到页面
3.更有语义的组织资源
基本原理
在组件容器里根据URL决定显示什么样的组件
REACT router特性(和后端路由对比)
1.声明式路由定义
通过react组件标签进行声明,可以放在任何地方,不需要具体的路由表进行声明
2.动态路由
传统路由一旦配置了它就是一个配置文件,成为一个静态文件
而react router的路由是页面在render的时候才会被解析的,有相应路由的标记标签就是有相应的配置,没有标签就没有相应的配置
三种路由实现方式
url路径:通过改变URl更改视图
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
34import React from "react";
import { BroswerRouter as Router, Route, Link } from "react-router-dom";
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About Us</h1>;
export default class RouterSample extends React.PureComponent {
render() {
return (
<Router>
<div>
<ul id="menu">
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/hello">Hello</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
<div id="page-container">
<Route path="/home" component={Home} />
<Route path="/hello" component={Hello} />
<Route path="/about" component={About} />
</div>
</div>
</Router>
);
}
}hash路由:使用Router 的HashRouter组件 进行路由容器包裹,切换路由时,
具体的路径会被放在URl的#后面,通过改变hash更变视图《兼容低版本浏览器》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
34import React from "react";
import { HashRouter as Router, Route, Link } from "react-router-dom";
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About Us</h1>;
export default class RouterSample extends React.PureComponent {
render() {
return (
<Router>
<div>
<ul id="menu">
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/hello">Hello</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
<div id="page-container">
<Route path="/home" component={Home} />
<Route path="/hello" component={Hello} />
<Route path="/about" component={About} />
</div>
</div>
</Router>
);
}
}存路由:使用react-router 的MemoryRouter组件进行路由容器包裹,路由信息放在内存中管理,URL不变的情况下,即可进行视图切换
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
35import React from "react";
import { HashRouter as Router, Route, Link } from "react-router-dom";
import { MemoryRouter } from "react-router";
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About Us</h1>;
export default class RouterSample extends React.PureComponent {
render() {
return (
<MemoryRouter>
<div>
<ul id="menu">
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/hello">Hello</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
<div id="page-container">
<Route path="/home" component={Home} />
<Route path="/hello" component={Hello} />
<Route path="/about" component={About} />
</div>
</div>
</MemoryRouter>
);
}
}
基于路由配置进行资源组织 好处
1.实现业务逻辑的松耦合
2.易于扩展,重构和维护
3.路由层面实现Lazy Load
REACT Router API
1.:普通链接,会触发浏览器刷新
类似a标签,但是不会触发浏览器的刷新,点击时router会接管导航,对切换进行处理不会传递到浏览器,让其进行真正的页面切换
to属性代表链接到的URl的地址
2.
可以添加activeClassName属性,当当前链接符合to属性值时,显示相应的样式 还有其他属性,详情请看react-router文档1
<NavLink to="/faq" activeClassName='selected'>FAQs</NavLink>
3.
切换页面时,跟用户提供一个确认的操作
1 | import { Prompt } from "react-router"; |
4.1
2
3
4
5
6
7
8import { Redirect,Route } from "react-router";
<Route exact path='/' render={()=>(
loggedIn?(
<Redirect to='/dashboard' />
) : (
<PublicHomePage/>
)
)}/>
5.
path:路由
component:相应要显示的组件
exact:是否精准配置path
多个route path都符合当前路由时,那相应组件都会进行显示1
<Route exact path="/" component={Home} />
6.
找到一个匹配的路径就只显示这个路径相应的组件,其他组件不显示1
2
3
4
5
6
7import { Switch,Route } from "react-router";
<Switch>
<Route path="/home" component={Home} />
<Route path="/hello" component={Hello} />
<Route path="/about" component={About} />
<Route component={Nomatch} />
</Switch>
参数传递
通过URL传递参数 :
获取参数:this.props.match.params
页面状态尽量通过URl参数定义,方便页面间跳转时数据传递,否则需要将数据转化成组件内部state进行渲染,过程复杂
套嵌路由
1.每个React组件都可以时路由容器
2.React 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69import React from "react";
import {
BrowserRouter as Router,
Route,
Link
} from "react-router-dom";
const Category = ({ match }) => (
<h1>Sub Category {match.params.subId}</h1>
);
const SubCategory = ({ match }) => (
<div>
<h1>Category {match.params.id}</h1>
<ul id="menu">
<li>
<Link to={`/category/${match.params.id}/sub/1`}>
Sub Category 1
</Link>
</li>
<li>
<Link to={`/category/${match.params.id}/sub/2`}>
Sub Category 2
</Link>
</li>
<li>
<Link to={`/category/${match.params.id}/sub/3`}>
Sub Category 3
</Link>
</li>
</ul>
<div id="page-container-2">
<Route
path="/category/:id/sub/:subId"
component={Category}
/>
</div>
</div>
);
export default class NestedRoute extends React.PureComponent {
render() {
return (
<Router>
<div>
<ul id="menu">
<li>
<Link to="/category/1">Category 1</Link>
</li>
<li>
<Link to="/category/2">Category 2</Link>
</li>
<li>
<Link to="/category/3">Category 3</Link>
</li>
</ul>
<div id="page-container">
<Route
path="/category/:id"
component={SubCategory}
/>
</div>
</div>
</Router>
);
}
}