# react-router-study
**Repository Path**: cai-lunduo/react-router-study
## Basic Information
- **Project Name**: react-router-study
- **Description**: react-router的学习记录
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-05-30
- **Last Updated**: 2021-05-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## react-router
### 介绍
### 安装
```shell
npm install --save react-router-dom
```
### 起步
`index.js`
```react
// ... 其他包导入
import {BrowserRouter} from 'react-router-dom'
ReactDOM.render(
,
document.getElementById('root')
);
```
如上所示,我们需要给根组件包裹一个`BrowserRouter`标签,这样子我们就可以在浏览器使用路由了。
在`react`中,路由即组件,简单用法如下:
```react
import { Link, Route } from 'react-router-dom'
function About() {
return (
关于页
)
}
function Home() {
return (首页
)
}
export default function RouteTest() {
return (
)
}
```
`Link`作用类似于`a`标签,会在页面展示让用户点击,而`Route`就是一个真正的路由映射组件,如上所示,`path`指定访问路径,`component`指定要展示的组件。其中因为`react-router`的路由包容性(只要path匹配到,就会渲染),我们还需对`path`为`/`的路由添加一个`exact`字段,这样子就只会精准匹配了。
### Router对象
被`Route`标签包裹的组件,传入的值就不是`props`了,而是一个路由器对象,我们可以打印看看路由器对象到底长啥样

如上所示,有`history`、`location`、`match`三个主要属性
```js
// 1.history: 导航指令
// 2.match: 获取参数信息
// 3.location: 当前url信息
```
### Switch
`react`路由是包容性的,也就是匹配到的路由都会被展示出来。但是我们可以通过`Switch`标签让`react`路由不再具有包容性,只展示匹配到的第一个路由:
```react
import { Link, Route, Switch, NavLink } from 'react-router-dom'
import { BrowserRouter } from 'react-router-dom'
function About(router) {
return about
}
function Home() {
return home
}
function NotFound() {
return (
not found
)
}
function App() {
return (
{/* 内联样式 */}
Home
about
{/* 一个switch为一组,只会展示第一个被匹配的组件 */}
)
}
```
如上所示,我们让`Switch`包裹的路由为一组,在这一组中只匹配第一个匹配到的路由则停止继续匹配,可以注意到我们在最后放了一个NotFound路由,这也是路由找不到时可以写的写法,因为没有`path`,前面的匹配不到则`NotFound`一定会被匹配到。
### Redirect
redirect就是重定向组件,有一个from和to属性
常用基础写法如下
```react
{/* 将from 定向到 to */}
{
return login ? :
}}>
```
### 子路由与动态路由
#### 子路由
子路由部分包括动态路由,那么在`react`中如何编写子路由呢?
举个例子,比如我们想要在上面的`About`页嵌套子路由,写法可以参考下面
```react
function About(params) {
return (
个人中心
个人信息
订单查询
Me
} />
order
} />
);
}
```
很简单,只要在`About`组件嵌套路由即可。
但是需要注意一点:
写子路由时父亲路由不能开启路由严格模式,即不能在父组件加个exact属性,否则一旦开启严格模式,子路由将不会被路由系统找到,从而匹配不到,如:
```react
import { Link, Route, Switch, NavLink, Redirect } from 'react-router-dom'
import { BrowserRouter } from 'react-router-dom'
function AAA() {
return (aaa
)
}
function BBB() {
return (bbb
)
}
function About(router) {
return (
a
b
)
}
function Home() {
return home
}
function App() {
return (
{/* 内联样式 */}
Home
about
{/* 一个switch为一组,只会展示第一个被匹配的组件 */}
)
}
export default App
```
在这里我们对`/about`路由开启了严格模式,而`About`组件下有子组件,但是我们会发现访问子组件的时候,子组件并没有展示出来,这是因为`/about`路由开启了严格模式从而导致子路由匹配不到。
#### 动态路由
动态路由对于在`url`传值的很简单,使用`:参数`即可,如果要通过`query`传值可以在`Route`加上相应的属性值,然后在对应组件的参数`路由对象`中的`match`字段便可拿到
```react
import {Link, Route, Switch, Redirect} from 'react-router-dom'
function Detail(props) {
return (
详情页:{props.match.params.id}
)
}
Detail
```
### 传参
react传参可以通过三种方式,可以通过params、query或者state对象进行传参
```react
import { Link, Route, Switch, NavLink, Redirect } from 'react-router-dom'
import { BrowserRouter } from 'react-router-dom'
import { useState } from 'react'
import qs from 'querystring'
/**
* 路由传参
*/
function Home(props) {
let [data] = useState([
{id: 1, title: '新闻'},
{id: 2, title: '财经'},
{id: 3, title: '体育'},
{id: 4, title: '文化'},
])
return (
{/* params传参 /home/:id/:title */}
{/* {
data.map(item => {item.title})
} */}
{/* query传参 /home?id=1&title=weibo */}
{/* {
data.map(item => {item.title})
} */}
{/* state参数 */}
{
data.map(item => {item.title})
}
)
}
// 子组件
function Total(props) {
console.log(props)
// params取值
// let {id, title} = props.match.params
// query取值
// let queryStr = props.location.search
// let queryObj = qs.parse(queryStr.slice(1))
// console.log(queryObj)
// state参数取值
let stateObj = props.location.state
console.log(stateObj)
return (
total
)
}
function App() {
return (
{/* 内联样式 */}
Home
{/* 一个switch为一组,只会展示第一个被匹配的组件 */}
)
}
export default App
```