React Router6学习(包括组件和Hooks)
- React Router6学习
- 1. 概述
- 1.1 React Router以三个不同的包发布到npm上,他们分别是
- 1.2 与React Router 5.x 版本相比,改变了什么?
- 2. Component
- 2.1
BrowserRouter
- 2.2
HashRouter
- 2.3
和 - 2.4
- 2.5
- 2.6
- 2.7
- 2.1
- 3. 上课笔记
- 1. 一级路由
- 2. 重定向
- 3. NavLink高亮
- 4. useRoutes重定向
- 5. 嵌套路由
- outlet
- to
- end
- 6. 路由的params参数以及useMatch钩子
- useMatch
- 7. 路由的search参数以及useLocation钩子
- useLocation
- 8. 路由的state参数
- 9. 编程式路由导航
- 10. useInRouterContext Hook的使用
- 11. useNavigationType() Hook的使用
- 12. useOutlet()
- 13. useResolvedPath()
- 1. 概述
React Router6学习
第1节和第2节是课程中的MD笔记, 第3节是在听课过程中自己记的笔记和从网上查的总结, 细节更多.
1. 概述
1.1 React Router以三个不同的包发布到npm上,他们分别是
- react-router:路由的核心库, 提供了很多的:组件、钩子。
- react-router-dom:包含react-router所有内容,并添加了一些专门用于DOM的组件,例如
等。 - react-router-native: 包括react-router所有内容,并添加一些专门用于ReactNative的API,例如:
等。
1.2 与React Router 5.x 版本相比,改变了什么?
- 内置组件的变化:移除了
,新增了
等。 - 语法的变化:
component={About}
变为了element={About}
等。 - 新增多个hook:
useParams
useNavigate
useMatch
等。 - 官方明确推荐函数式组件了。
2. Component
2.1 BrowserRouter
- 说明:
用于包裹整个应用。 - 示例代码:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from "react-router-dom"
import App from './App';
ReactDOM.render(
,document.getElementById('root')
);
2.2 HashRouter
- 说明:作用和
一样, 但是
修改的是地址的hash值。 - 备注:6.x版本中
与
的用法与5.x相同。
2.3
和
-
V6版本中移除了先前的
Switch
,引入了全新的替代者Routes
; -
Routes
和Route
要搭配使用,并且必须要用Routes
包裹Route
; -
Route
相当于一个if语句,如果路径与当前URL匹配,则呈现其对应的组件。 -
属性用于指定:匹配时是否区分大小写(默认为false)。 -
当URL发生变化时,
都会查看其所有子
元素以找到最佳匹配并呈现组件。 -
也可以嵌套使用,且可以配合useRoutes()
配置“路由表”,但需要通过
组件来渲染其子路由。 -
示例代码:
} />
} />
}/>
2.4
-
作用: 修改URL, 且不发送网络请求(路由链接).
-
注意: 外侧需要用
或
包裹 -
示例代码:
import {Link} from 'react-router-dom' function Test() { return (
按钮) }
2.5
- 作用: 与
组件类似, 且可实现导航的"高亮"效果.
2.6
- 作用:只要
组件被渲染,就会修改路径,切换视图。 replace
属性用于控制跳转模式 (push 或 replace,默认是push)
2.7
- 当
产生嵌套时,渲染其对应的后续子路由。 - 在后续路子由组件的想要展示的位置上使用
, 即可渲染。
3. 上课笔记
1. 一级路由
首先需要安装react路由包: npm i react-router-dom
-
使用路由:在App.jsx中从
react-router-dom
中引入BrowserRouter
来包裹App
组件 -
创建路由链接:可以使用
react-router-dom
中的link
和NavLink
来创建路由链接,其中NavLink
可具有高亮效果。
以前我们的应用如果需要在各个页面之间切换,使用锚点元素实现的话,在每次点击时,页面会被重新加载,React Router提供了 和
组件最终会被渲染成HTML标签的url的时候给已经渲染的元素添加参数,组件的属性有:来避免这种情况的发生。当你点击时,url会更新,组件会被重新渲染,但是页面不会重新加载。
activeClassName(string):设置选中样式,默认值为active- 需要将className写成一个函数:
- activeStyle(object):当元素被选中时,为此元素添加样式
- exact(bool):为true时,只有当导致和完全匹配class和style才会应用
- strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
- isActive(func)判断链接是否激活的额外逻辑的功能
————————————————
版权声明:本文为CSDN博主「冰雪为融」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lhjuejiang/article/details/80366839
- 注册路由:使用的组件由
SWitch
(已删除)改为Routes
,还要需要使用Route
,Route
是用来被包裹的,一个
来包裹多个
, 语法为:
router path 代表的是路由链接地址,React Component代表的是如果匹配成功所使用的组件名字。
}>
2. 重定向
当我们什么路由链接都没输入,就相当于是'/'时,就会出现警告,No routes matched location "/", 这个时候我们就需要使用重定向来解决问题。
使用的组件由Redirect
改为Navigate
,语法为, 其中about为匹配不到路径时所跳转到的组件:
} />
Navigate
组件只要渲染就会引起视图的切换,可以用此特性来控制当页面达到某一条件时,启用Navigate
组件来进行视图切换,举一个小例子
import React, {useState} from 'react'
import { Navigate } from 'react-router-dom'
export default function Home() {
const [count,setCount] = useState(0)
return (
我是Home的内容
{
count === 2 ? : 当前count值是{count}
}
)
}
其实Navigate
组件中还有一个属性,replace, 可以控制跳转的模式,默认为false, 即push模式。
} />
3. NavLink高亮
NavLink路由链接在点击的时候,会给他加一个class属性,值默认是active,在使用bootstrap的时候就会出现高亮效果。
首先我们要知道在我们点击一个连接的时候,会传入一个对象,里面有isActive属性,值为true。
利用这个特性我们可以写一个函数来计算样式,然后在className中使用这个函数,关键代码如下:
function computedClassName({isActive}) {
return isActive? 'list-group-item atguigu': 'list-group-item'
}
{/* 路由链接 */}
About
Home
4. useRoutes重定向
之前我们是这样注册路由的:
} />
} />
}/>
其实可以发现中间除了path值和element值不一样以外,基本都是相同的结构,所以我们就可以使用useRoutes来注册路由。
在我们有路由的项目中,一般会有两个特殊的文件夹,一个是pages,里面存放的是各个路由的组件。另外一个是routes,里面存放的是路由表,里面的index.js一般是如下类似代码:
import About from '../pages/About'
import Home from '../pages/Home'
import { Navigate } from 'react-router-dom'
// 创建路由表,可以用来注册路由
const routerList = [
{
path:'/about',
element:
},
{
path:'/home',
element:
},
{
path:'/',
element:
},
]
export default routerList;
然后我们只需要在需要使用注册路由的组件里使用useRoutes
Hooks来实现了:
import {NavLink,useRoutes} from "react-router-dom"
export default function App() {
// 根据路由表生成对应的路由
const element = useRoutes(routerList)
......
{/* 路由链接 */}
About
Home
{/* 注册路由 */}
{element}
......
}
这样做的好处是可以把整个应用所有的路由都可以在routes文件夹下进行统一的管理,而且能够让代码可读性更好,也契合了未来Hooks发展的方向。
5. 嵌套路由
outlet
Outlet
像是一个槽位,如果匹配上了就在Outlet
组件所在的地方进行组件的展示,也就是说Outlet
可以指定组件呈现的位置。
to
to
属性内可以直接写最终地址,比如之前是/home/news
, 现在可以直接写news
,注意不要写成/news
, 否则就成了从一级路由news里找,即从根路径下开始找。
routes/index.js
import About from '../pages/About'
import Home from '../pages/Home'
import { Navigate } from 'react-router-dom'
import Message from '../pages/Message'
import News from '../pages/News'
// 创建路由表,可以用来注册路由
const routerList = [
{
path:'/about',
element:
},
{
path:'/home',
element: ,
children:[
{
path:'news',
element:
},
{
path:'message',
element:
}
]
},
{
path:'/',
element:
}
]
export default routerList;
Home.jsx关键代码:
import React from 'react'
import { NavLink, Outlet } from 'react-router-dom'
export default function Home() {
return (
我是Home的内容
-
News
-
Message
{/* 指定路由组件呈现的位置 */}
)
}
一共有三种路由路径的书写方式,以二级路由home组件下的news为例:
- to='/home/news'
- to='news'
- to='./news'
end
还有一个值得一提的事是,目前我们页面所呈现的高亮的地方不仅有news, 而且还有一级路由home也是高亮的,我们如果不想让他高亮,那么就可以在该组件上加一个属性end
,来代表当匹配的是该路由的子路由时,该路由不高亮。
Home
6. 路由的params参数以及useMatch钩子
一共有三种方式可以在路由进行传参操作:1. params参数 2. search 3. location.state
我们首先讲第一种,使用params参数:
// 1.Link路由链接的书写方式
{message.title}
// 2.路由表匹配规则
{
path:'detail/:id/:title/:content',
element:
}
// 接收使用
import { useParams } from "react-router-dom"
export default function Detail() {
// 接收得到的参数是一个对象,我们可以使用结构的方式来获得他
const { id, title, content } = useParams()
return (
- 消息编号:{id}
- 消息标题:{title}
- 消息内容:{content}
)
}
useMatch
我们还可以使用useMatch
钩子来获得之前match里面的参数,比如patten里的path参数等,具体使用语法如下,我们需要在所需要使用match参数的组件里把当前路径包括params写好:
import {useMatch} from "react-router-dom"
......
const match = useMatch('/home/message/detail/:id/:title/:content')
console.log(match)
7. 路由的search参数以及useLocation钩子
一共有三种方式可以在路由进行传参操作:1. params参数 2. search 3. location.state
我们来介绍第二种, 使用serach:
// 1. search传参的书写方式
messages.map(message => {
return (
// 路由链接
{/* search传参 */}
{message.title}
)
})
// 2.routes路由表不用改变任何东西
// 3.在接收参数的组件里,要使用useSearchParams hook来接收参数
import React from 'react'
import { useSearchParams } from 'react-router-dom'
export default function Detail() {
// 类似于useState的使用方式,所存放的数据在search.get('...')里
const [search, setSearch] = useSearchParams()
return (
- 消息编号:{search.get('id')}
- 消息标题:{search.get('title')}
- 消息内容:{search.get('content')}
)
}
useLocation
另外我们还可以使用useLocation
钩子来获得loaction的数据,里面包括了pathname和经过转化后的search,具体的语法是:
import { useLocation } from 'react-router-dom'
......
const location = useLocation()
console.log(location);
8. 路由的state参数
一共有三种方式可以在路由进行传参操作:1. params参数 2. search 3. location.state
我们来介绍第三种, 使用location.state,当然就是使用的上面提到过的useLocation
钩子:
// 1. 路由链接
{/* state传参 */}
{message.title}
// 2. routes路由表不需要做任何的改动,同search一样
// 3. 在接收参数的组件里,要使用useLocation hook来接收参数
import React from 'react'
import { useLocation } from 'react-router-dom'
export default function Detail() {
const location = useLocation()
const { id, title, content } = location.state
return (
- 消息编号:{id}
- 消息标题:{title}
- 消息内容:{content}
)
}
9. 编程式路由导航
之前我们都是借助this.props.history
来对对象上的API对操作路由跳转\前进和后退, 可是在函数式组件中我们并不能使用this, 这个时候我们借助useNavigate
这个Hook来实现.
首先我们来对其中的replace和state传参来进行说明:
// 引入useNavigate钩子
import { Link, Outlet,useNavigate } from 'react-router-dom'
// 使用钩子,得到的navigate是一个函数
const navigate = useNavigate()
const showDetail = (message) => {
const {id, title, content} = message
navigate('detail',{
// 指定是否为替换的方式
replace:false,
// 传递state参数
state:{
id,
title,
content
}
})
}
// 在组件上使用函数来使用该navigate函数
但是我们知道在之前的react router5里面非路由组件是不能使用this.props.history
的, 但是在react router6里面, 我们只需要使用useNavigate
这个钩子, 就可以实现非路由组件使用编程式路由导航, 并且可以实现页面的回退和前进, 具体实现如下所示, components文件夹(此文件夹存放非路由组件)下的Header组件源代码如下所示:
import React from 'react'
import { useNavigate } from 'react-router-dom'
export default function Header() {
const navigate = useNavigate()
const backward = () => {
navigate(-1)
}
const forward = () => {
navigate(1)
}
return (
React Router6 Demo
)
}
10. useInRouterContext Hook的使用
作用: 如果组件在
的上下文中呈现, 则useInRouterContext
钩子返回为 true
, 否则返回 false
.
比如说我们的App组件是被
11. useNavigationType() Hook的使用
- 作用:返回当前的导航类型(用户是如何来到当前页面的)
- 返回值:
POP
PUSH
REPLACE
- 备注:
POP
是指在浏览器中直接打开了这个路由组件(刷新页面)
12. useOutlet()
- 作用, 用来呈现当前组件中要渲染的嵌套路由
- 示例代码:
const result = useOutlet()
console.log(result)
// 如果嵌套路由没有挂载,则result为null
// 如果嵌套路由已经挂载,则展示嵌套的路由对象
13. useResolvedPath()
- 作用: 给定一个url值, 解析其中的: path search 和 hash值.