React - Router 快速入门
MaHongli 2020-06-04 React
# react-router
# react-router 基本介绍
react-router 是官方提供的和 react 配套的前端路由库。
整个react-router被拆分为了4个包:
- react-router:核心包
- react-router-dom:在浏览器端的前端导航
- react-router-native:react native 上面的导航
- react-router-config:router 相关的配置
我们搭建项目的时候,直接安装react-router-dom依赖库即可。里面包含了核心包的内容。
npm i react-router-dom
1
首先需要在 index.js 的根组件最外层引入 BrowserRouter 或者 HashRouter,代码如下:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { HashRouter } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<HashRouter>
<App />
</HashRouter>
</React.StrictMode>,
document.getElementById('root')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
接下来,在 App.js 里面配置路由的跳转
import React from 'react'
import { Route, Switch, Redirect, NavLink } from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
export default function App() {
return (
<div>
{/* 页头 */}
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
{/* 左边导航 */}
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/*导航路由链接*/}
<NavLink className="list-group-item" activeClassName='activeClass' to='/home'>Home</NavLink>
<NavLink className="list-group-item" activeClassName='activeClass' to='/about'>About</NavLink>
</div>
</div>
{/* 右边内容区域 */}
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/*可切换的路由组件*/}
<Switch>
<Route exact path='/' component={Home} />
<Route path='/home' component={Home} />
<Route path='/about' component={About} />
</Switch>
</div>
</div>
</div>
</div>
</div>
);
}
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
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
# 嵌套路由
嵌套路由很简单,直接在要设置嵌套路由的组件中,再次配置路由即可。
import React from 'react';
import {NavLink,Switch,Route,Redirect} from 'react-router-dom'
import News from './News'
import Message from './Message'
const Home = () => {
return (
<div>
<h2>Home 页面</h2>
<div>
<ul className="nav nav-tabs">
<li>
<NavLink to='/home/news'>News</NavLink>
</li>
<li>
<NavLink to='/home/message'>Message</NavLink>
</li>
</ul>
<Switch>
<Route exact path='/home/news' component={News}/>
<Route exact path='/home/message' component={Message}/>
<Redirect to='/home/news' />
</Switch>
</div>
</div>
);
}
export default Home;
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
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
# 动态路由
首先要在Link或者NavLink后面设置动态的参数,然后在Route的path属性中通过冒号的形式接收动态参数
import React, { useState, useEffect } from 'react';
import { NavLink, Route } from 'react-router-dom'
import MessageDetail from './MessageDetail'
let stopTimer;
const Message = (props) => {
const [item, setItem] = useState([]);
useEffect(() => {
stopTimer = setTimeout(() => {
const data = [
{ id: 1, title: '号外!昨天下午竟然放假' },
{ id: 2, title: '是道德沦丧还是人性泯灭,竟然不让我上课!' },
{ id: 3, title: '惊!特朗普竟然不敌拜登' },
];
setItem(data)
}, 1000)
return ()=>{
clearTimeout(stopTimer)
}
})
// 获取到当前的路由
const path = props.match.path;
return (
<div>
<ul style={{ marginTop: '20px' }}>
{
item.map(it => <li key={it.id}><NavLink to={`${path}/${it.id}`}>{it.title}</NavLink></li>)
}
</ul>
<Route path={`${path}/:id`} component={MessageDetail}></Route>
</div>
);
}
export default Message;
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
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
接下来,在详情页,首先要接收传递过来的动态参数,props.match.params.id 来接收,接收完毕后,通过这个id拿具体的信息
import React, { useState, useEffect } from 'react'
const newsDetail = [
{ id: 1, title: '号外!昨天下午竟然放假', content: '某某金牌讲师竟然不让学生上课,打算用作业来弥补!' },
{ id: 2, title: '是道德沦丧还是人性泯灭,竟然不让我上课!', content: '某某戴帽子的学生表面很生气,内心开心!但是有作业,突然又不开心' },
{ id: 3, title: '惊!特朗普竟然不敌拜登', content: '某某金牌讲师,用这个打赌,赢了一顿火锅!' },
]
export default function MessageDetail(props) {
const [detail, setDetail] = useState({});
useEffect(() => {
const id = props.match.params.id; //拿到传递过来的 id
setDetail(newsDetail.find(it => it.id == id));
}, [props.match.params.id])
return (
<div>
<ul style={{ marginTop: '20px' }}>
<li>新闻编号:{detail.id}</li>
<li>新闻标题:{detail.title}</li>
<li>新闻内容:{detail.content}</li>
</ul>
</div>
)
}
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
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
# 编程式导航
import React, { useState, useEffect } from 'react';
import { NavLink, Route } from 'react-router-dom'
import MessageDetail from './MessageDetail'
let stopTimer;
const Message = (props) => {
const [item, setItem] = useState([]);
useEffect(() => {
stopTimer = setTimeout(() => {
const data = [
{ id: 1, title: '号外!昨天下午竟然放假' },
{ id: 2, title: '是道德沦丧还是人性泯灭,竟然不让我上课!' },
{ id: 3, title: '惊!特朗普竟然不敌拜登' },
];
setItem(data)
}, 1000)
return ()=>{
clearTimeout(stopTimer)
}
})
// 获取到当前的路由
const path = props.match.path;
const showDetail = (e)=>{
props.history.push(`${path}/${e.target.dataset.id}`)
}
const showDetail2 = (e)=>{
props.history.replace(`${path}/${e.target.dataset.id}`)
}
const back = ()=>{
props.history.goBack();
}
const forward = ()=>{
props.history.goForward();
}
return (
<div>
<ul style={{ marginTop: '20px' }}>
{
item.map(it => <li key={it.id}>
<NavLink to={`${path}/${it.id}`}>{it.title}</NavLink>
<button className='btn btn-info btn-xs' onClick={showDetail} data-id={it.id}>查看详情(push)</button>
<button className='btn btn-info btn-xs' onClick={showDetail2} data-id={it.id}>查看详情(replace)</button>
</li>)
}
</ul>
<div>
<button className='btn btn-info btn-xs' onClick={back}>返回</button>
<button className='btn btn-info btn-xs' onClick={forward}>前进</button>
</div>
<Route path={`${path}/:id`} component={MessageDetail}></Route>
</div>
);
}
export default Message;
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
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