react-router-dom 6使用指北
React-router-dom 6 应用
一 一级路由
下载react-router-dom
react-router-dom6已经是默认路由版本
yarn add react-router-dom
完成基本路由功能
使用函数式组件
- index.js引入BroswerRouter或者HashRouter标签包裹app根标签
- 组件内引入
Routers
Router
NavLink
- 组件内引入需要作为路由的子组件
import React from 'react'
import { NavLink, Routes, Route } from 'react-router-dom'
import Message from './pages/message'
import Profile from './pages/profile'
export default function App() {
return (
<div>
<h1>react router dom</h1>
<ul className="nav nav-pills">
{/*路由导航区*/}
<li role="presentation"><NavLink to="/profile">Profile</NavLink></li>
<li role="presentation"><NavLink to="/message">Messages</NavLink></li>
</ul>
{/*路由展示区*/}
<h1>
{/*必须使用Routes包裹Route*/}
<Routes>
<Route path="profile" element={<Profile/>} />
<Route path='message' element={<Message/>}/>
</Routes>
</h1>
</div>
)
}
//01-一级路由
二 重定向
重定向使用Navigate
Navigate基本使用:
重定向路径
<Route path="/" element={<Navigate to="/profile"/>}/>
依据条件改变路径渲染对应组件
{count === 2 ? <Navigate to="/Message" /> : <h1>count:{count}</h1>}
Navigate可以使用push或者replace方式改变路径
<Navigate to="/Message" replace={true}/>
<Navigate to="/Message" push={true}/>
三 路由组件的高亮效果
- 使用navlink作为路由标签
- 在className内部使用函数
- 函数返回值是类名
- 该函数有一个形参,是一个对象
{isActive:true}
- 可以使用对象解构解构该形参
使用实例
当路由处于活跃状态时,路由链接添加active类名
<NavLink to="/profile" className={({isActive}) => isActive? 'active':''}>Profile</NavLink>
四 useRoutes路由表
import {useRoutes} from 'react-router-dom'
前面使用的route是使用一堆Routes、Route之类的冗余代码作为占位符在项目内部的,这样使用的路由,不宜维护,且打乱了代码结构,为了防止这种情况,我们使用useRoutes钩子函数创建路由表来解决
useRoutes使用方法
一 创建路由表
在组件函数内部,调用useRoutes函数,并接收其返回值
const element = useRoutes([
{
path: '/profile',
element: <Profile/>
},
{
path: '/message',
element: <Message/>
},
{
path: '/',
element: <Navigate to='/profile'/>
}
])
二 组件结构内使用函数返回值作为占位符
return (
<div>
<ul className="nav nav-pills">
{/*路由导航区*/}
<li role="presentation"><NavLink to="/profile" >Profile</NavLink></li>
<li role="presentation"><NavLink to="/message">Messages</NavLink></li>
</ul>
{/*路由展示区*/}
<h1>
{element}
</h1>
</div>
三 单独创建routes文件夹管理路由表
在src文件夹下创建一个routes/index.js
import { Navigate } from "react-router-dom"
import Profile from "../pages/Profile"
import Message from "../pages/Message"
export default [
{
path: '/profile',
element: <Profile/>
},
{
path: '/message',
element: <Message/>
},
{
path: '/',
element: <Navigate to='/profile'/>
}
]
组件内部导入该文件
import routes from './routes'
使用
const element = useRoutes(routes)
{element}
五 嵌套路由
在一级路由下面创建二级子路由
- 引入路由路由占位符OutLet到组件中
- 引入NavLink到组件中改变路径,子路由路径可以不需要加
/
import React from 'react'
import { NavLink, Outlet } from 'react-router-dom'
export default function Message() {
return (
<div>
<ul>
<li>
<NavLink to='message1'>message1</NavLink>
</li>
<li>
<NavLink to='message2'>message2</NavLink>
</li>
</ul>
{/*路由占位符*/}
<Outlet/>
</div>
)
}
- 在路由表中添加属性
children
,该属性下创建对应子路由
import { Navigate } from "react-router-dom"
import Profile from "../pages/Profile"
import Message from "../pages/Message"
import Message1 from '../pages/Message/Message1'
import Message2 from '../pages/Message/Message2'
export default [
{
path: '/profile',
element: <Profile/>
},
{
path: '/message',
element: <Message />,
children: [
{
path: 'message1',
element: <Message1/>
},
{
path: 'message2',
element: <Message2/>
}
]
},
{
path: '/',
element: <Navigate to='/profile'/>
}
]
六 路由传参
6.1 Params传参
可以通过useParams函数传递参数
使用路由链接传参方式:
1. Link组件to到动态路径
data.map(item => <li key={item.id}><Link to={`showparams/${item.id}/${item.name}/${item.message}`}>{item.name}的信息</Link></li>)
2. 路由匹配采用动态匹配
{
path: 'showparams/:id/:name/:message',
element:<ShowParams/>
}
3. 使用useParams函数接收参数
import {useParams} from 'react-router-dom'
const {id,name,message} = useParams()
4. 不要忘记使用Outlet作为占位符
5. 使用useMatch也可以解析路径获取参数(少用,了解)
6.2 search传参
使用useSearchParams传参
1. 使用search参数作为路由链接
data.map(item => <li key={item.id}><Link to={`showparams?id=${item.id}&name=${item.name}&message=${item.message}`}>{item.name}的信息</Link></li>)
2. 路由表不需带参
3. 使用useSearchParams解析参数
import { useSearchParams } from 'react-router-dom'
const [search, setSearch] = useSearchParams()
const id = search.get('id')
const name = search.get('name')
const message = search.get('message')
6.3 state传参
1. 路由链接正常写,navlink或者link添加state参数
data.map(item => <li key={item.id}><Link to="showparams"
state={{id:item.id,name:item.name,message:item.message}}
>{item.name}的信息</Link></li>)
2. 在路由组件内使用useLocation方法解析出state内容
import { useLocation } from 'react-router-dom'
const { state:{id,name,message} } = useLocation()
3. 路由表正常写
七 路由懒加载
使用lazy函数
// 1. 引用lazy
import { lazy } from 'react'
// 2. 使用lazy函数引入路由文件
const LoginPage = lazy(() => import('../pages/LoginPage'))
// 3. 路由表中直接使用即可
export default [
{
path: '/login',
element: <LoginPage/>
}
]
八 编程式路由导航
使用useNavigate完成编程式路由导航
1. 引入useNavigate
import {useNavigate} from 'react-router-dom'
2. 使用navigate接收该函数返回值
const navigate = useNavigate()
3. 将返回值作为一个函数调用
调用格式:navigate(路径,配置)
配置表:
replace跳转方式 | state传递状态 |
---|---|
replace/push (boolean) | 对象,state传参的参数 |
navigate('showparams',{
replace:true,
state:{
id:item.id,
name:item.name,
message:item.message
}
})
实例
import React from 'react'
import { Link,Outlet,useNavigate } from 'react-router-dom'
export default function Message1() {
//调用useNavigate获取返回值
const navigate = useNavigate()
const data = [
{ id: 1, name: 'ylf', message: 'ylf的信息' },
{ id: 2, name: 'li', message: 'li的信息' },
{ id: 3, name: 'fei', message: 'fei的信息' }
]
//路由跳转函数
function showMsg(item) {
navigate('showparams', {
replace: true,
state: {
id: item.id,
name: item.name,
message:item.message
}
})
}
return (
<div>
<span>message1</span>
<ul>
{
data.map(item => <li key={item.id}>
{/*点击调用函数,需要使用函数返回值形式调用*/}
<button onClick={()=>showMsg(item)}>点击查看详细信息</button>
</li>)
}
</ul>
<Outlet />
</div>
)
}
navigate可以直接传递数字跳转
<button type="button" class="btn btn-default" onClick={()=>navigate(1)}>前进</button>
<button type="button" class="btn btn-default" onClick={()=>navigate(-1)}>后退</button>
九 其他hooks函数
直接在组件中调用即可
useRouterContext
作用:判断组件是否被路由包裹
useNavigationType
作用:判断路由跳转方式
返回值:push
pop
replace
pop是在浏览器中直接打开了这个路由的组件
useOutlet
作用:查看组件下级路由信息
组件若未被挂载则返回null,若以被挂载,则返回该子组件信息
useResolvePath
作用:解析路径
useResolvedPath("https://www.bilibili.com/video/BV1wy4y1D7JT?p=140&spm_id_from=pageDriver")
转载自:https://juejin.cn/post/7080422028246777863