react-router-dom@6
路由的三种模块
-
react-router:核心模块,包含 React 路由大部分的核心功能,包括路由匹配算法和大部分核心组
件和钩子。 -
react-router-dom:React应用中用于路由的软件包,包括react-router的所有内容,并添加了一
些特定于 DOM 的 API,包括但不限于BrowserRouter、HashRouter和Link。 -
react-router-native: 用于开发React Native应用,包括react-router的所有内容,并添加了一些
特定于 React Native 的 API,包括但不限于NativeRouter和Link。
与之前的变化
-
path:与当前页面对应的URL匹配。 -
element:用于决定路由匹配时渲染哪个组件,代替component和render。 -
<Outlet></Outlet>让嵌套路由更简单 -
useNavigate代替useHistory - 移除了
activeClassName和activeStyle - 钩子
useRoutes代替react-router-config
使用
一级 多级
- index用于嵌套路由,仅匹配父路径时,设置渲染的组件。
<Routes>
<Route index path='/film' element={<Film />}/>
<Route path='/cinema' element={<Cinema />}/>
<Route path='/center' element={<Center />}/>
<Route path='/cinema/search' element={<Search />}/>
<Route path='*' element={<NotFound/>}/>
</Routes>
路由重定向
1: 使用 Navigate 组件替代(官方推荐方案)
{/* <Route index element={<Film/>}/> */}
2: 自定义 Redirect 组件(官方推荐方案)
<Route path="*" element={<Redirect to="/film"/>}/>
function Redirect({to}){
const navigate =useNavigate()
useEffect(() => {
navigate(to,{replace:true})
})
return null
}
- 404如何实现?
<Route path="/" element={<Redirect to="/film"/>}/>
<Route path="*" element={<NotFound/>}/>
嵌套路由
<Routes>
<Route path='/film' element={<Film />}>
{/* <Route index element={<Nowpalying/>}/> */} { /* 嵌套重定向一 index */ }
<Route path='' element={<Redirect to='/film/nowplaying'/>}/> { /* 嵌套重定向写法二 path路径默认情况 重定向到nowplaying组件 */ }
<Route path='/film/nowplaying' element={<Nowpalying/>}/> { /* 嵌套写法 :1. 绝对路径写法 */ }
<Route path='comingsoon' element={<Comingsoon/>}/> { /* 嵌套写法 :2. 相对路径写法 */ }
</Route>
<Route path='/cinema' element={<Cinema />}/>
<Route path='/center' element={<Center />}/>
<Route path='/cinema/search' element={<Search />}/>
{/* <Route path="*" element={<Navigate to="/films"/>}/> */}
<Route path='/' element={<Redirect to={'/film'}/>}/>
<Route path='*' element={<NotFound/>}/>
</Routes>
声明式导航和编程式导航
声明式:<a href=' / ' ></a>
编程式:location.href = ' / '
声明式导航
- NavLink 与 Link 都可以实现路由跳转,NavLInk 拥有 active
- className 接收一个回调函数 ,active返回true,其他返回false
<NavLink to='/film' className={({isActive})=>isActive?'tabbar-active':''}>电影</NavLink>
编程式导航
//url传参
const navigate = useNavigate()
navigate(`/detail?id=${id}`)
//获取url参数 import { useSearchParams } from 'react-router-dom'
const [searchParams, setSearchParams] = useSearchParams()
// 获取参数
searchParams.get('id')
// 判断参数是否存在
searchParams.has('id')
// 同时页面内也可以用set方法来改变路由
setSearchParams({"id":2})
动态传参
//跳转页面,路由传参
navigate(`/detail/${id}`)
//配置动态路由
<Route path="/detail/:id" element={<Detail/>}/>
//获取动态路由参数
const {id} = useParams()
路由拦截
<Route path="/center" element={
<AuthComponent>
<Center></Center>
</AuthComponent> }/>
function AuthComponent({children}){
return localStorage.getItem("token")? children:<Redirect to="/login"/>
}
withRouter / 类组件跳转方法
- v6 中没有 withRouter 方法
- 在旧的类组件项目中可通过封装高阶组件实现
方法封装
import React from 'react'
import {
useNavigate,
useParams,
useLocation
} from 'react-router-dom'
export default function withRouter(Component) {
return function (props) {
const push = useNavigate()
const match = useParams()
const location = useLocation()
return <Component {...props} history={{push, match, location}}/>
}
}
路由懒加载
- 方法封装
import React from "react"
const LazyLoad = (path)=>{
const Comp = React.lazy(()=>import(`../views/${path}`))
return (
<React.Suspense fallback={<>加载中....</>}>
<Comp/>
</React.Suspense>
)
}
export default LazyLoad
useRoutes钩子配置路由
import Redirect from '../components/Redirect';
import AuthComponent from '../components/AuthComponent';
import { useRoutes } from 'react-router-dom';
import LazyLoad from '../components/LazyLoad'
export default function MRouter() {
const routes = useRoutes([
{
path: '/film',
element: LazyLoad('Film'),
children: [
{
path: '',
element: <Redirect to={'/film/nowplaying'}/>
},
{
path: '/film/nowplaying',
element: LazyLoad('film/Nowplaying')
},
{
path: 'co mingsoon',
element: LazyLoad('film/Comingsoon')
}
]
},
{
path: '/cinema',
element: LazyLoad('Cinema')
},
{
path: '/center',
element: <AuthComponent>
{LazyLoad('Center')}
</AuthComponent>
},
{
path: `/detail/:id`,
element: LazyLoad('Detail')
},
{
path: '/cinema/search',
element: LazyLoad('Search')
},
{
path: 'login',
element: LazyLoad('Login')
},
{
path: '/',
element: LazyLoad('/film')
},
{
path: '*',
element: LazyLoad('NotFound')
}
])
return (
routes
)
}