安装 : npm install react-router-dom
定义路由规则
src/router/index.js
import React from 'react'import Film from '../views/Film';...//Routes代替了switchimport {Route,Routes} from 'react-router-dom'export default function MRouter () {return (<Routes><Route path="/films" element={<Film />} /><Route path="/cinemas" element={<Cinema />} /><Route path="/center" element={<Center />} /></Routes>)}
导入路由
App.js
import {HashRouter} from 'react-router-dom'
import MRouter from '../src/router'
function App() {
return (
<HashRouter>
<MRouter></MRouter>
</HashRouter>
);
}
export default App;
重定向 & 404
v6没有Redirect,推荐使用Navigate
import React from 'react'
import {Route,Routes,Navigate} from 'react-router-dom'
import Redirect from '../components/Redirect';
import NotFound from '../views/NotFound'
export default function MRouter () {
return (
<Routes>
...
//重定向方式一(不推荐) :自定义Redirect组件
<Route path="/" element={<Redirect to="/films"/>}/>
//重定向方式二(推荐) :使用Navigate
<Route path='/' element={<Navigate to="/films"/>}/>
//404 *匹配所有 该规则要放到最后
<Route path='*' element={<NotFound/>}/>
</Routes>
)
}
Redirect组件
import {useEffect} from 'react'
import { useNavigate } from 'react-router-dom'
export default function Redirect({to}) {
const navigate = useNavigate()
useEffect(() => {
navigate(to,{replace:true})
})
return null
}
嵌套路由
定义
src/router/index.js
export default function MRouter () {
return (
<Routes>
<Route path="/films" element={<Film />} >
//子路由
<Route path="nowplaying" element={<Nowplaying/>} />
<Route path="comingsoon" element={<Comingsoon/>} />
//index父路径 访问/films时重定向到/films/nowplaying
<Route index element={<Navigate to="/films/nowplaying"/>}/>
</Route>
</Routes>
)
}
路由容器 & 使用
Film组件
import React from 'react'
import {Outlet} from 'react-router-dom'
export default function Cinema () {
return (
<div>
Filme
//子路由容器
<Outlet></Outlet>
</div>
)
}
声明式导航与编程式导航useNavigate
声明式: <NavLink to"">
编程式: useNavigate()
声明式跳转传参
import {NavLink} from 'react-router-dom'
export default function Tabbar(){
return(
<div>
<li>
<NavLink to='/films' className={({isActive})=>isActive?'kerwinactive':''}>电影</NavLink>
</li>
</div>
)
}
编程式导航跳转传参
import {useNavigate} from 'react-router-dom'
//url跳转传参
const navigate = useNavigate()
//指定跳转
navigate(`/detail?id=${id}`)
//replace
navigate('/child1/child1B',{replace: true})
// 历史记录 前进
navigate(1)
// 历史记录 后退
navigate(-1)
// 历史记录 后退两步
navigate(-2)
参数获取
//获取url参数
import { useSearchParams } from 'react-router-dom'
const [searchParams, setSearchParams] = useSearchParams()
// 获取参数
searchParams.get('id')
// 判断参数是否存在
searchParams.has('id')
// 同时页面内也可以用set方法来改变路由
setSearchParams({"id":2})
路由传参
params
params
//params 参数传参路由定义
<Route path="/detail/:myid" element={<Detail />} />
//params传参
const navigate = useNavigate()
navigate(`/detail/${id}`)
//params 参数接收
import { useParams } from 'react-router-dom'
const { myid } =useParams()
console.log(myid);
声明式
需配置路由 /toogle/:id
<Link to={'/toggle/123'}></Link>
query | search
编程式
import { useSearchParams } from 'react-router-dom'
//query 传参
const navigate = useNavigate()
navigate(`/detail?id=${id}`)
//query 参数接收
const [searchParams, setSearchParams] = useSearchParams()
console.log(searchParams.get('id'));
声明式
不用配置路由
<Link to={'/toggle?age=20&name=zhangsan'}></Link>
state
编程式
//state 传参
const navigate = useNavigate()
navigate("/exam",{state: {...})
//query 参数接收
const location = useLocation()
console.log(location.state);
声明式
不用配置路由
<Link to={'/toggle'} state= {{title: this.state.exam.title}}></Link>
路由地址 useLocation
const { pathname } = useLocation()
路由拦截
如果跳转到center没有token则去login页面
//路由规则
export default function MRouter () {
return (
<Routes>
//Center组件作为参数传入
<Route path="/center" element={<AuthComponent><Center /></AuthComponent>} />
<Route path="/login" element={<Login/>}/>
</Routes>
)
}
//是否登录判断逻辑
function AuthComponent({children}){
const isLogin = localStorage.getItem('token')
//没有登录则到login
return isLogin ? children : <Navigate to="/login"/>
}
路由模式
import {HashRouter} from 'react-router-dom'
import {BrowserRouter} from 'react-router-dom'
withRouter / 类组件跳转方法
v6没有withRouter , 实现方法如下:
- hooks函数组件可以用
const navigate = useNavigate() - 类组件自定义
withRouter自定义
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()
//props 将组件原有的props返回 同时增加history
return <Component {...props} history={{push,match,location}}/>
}
}
使用
import React, { Component } from 'react'
import withRouter from '../../components/withRouter'
class FilmItem extends Component {
render() {
return (
<li onClick={()=>this.handleClick(this.props.filmId)}>
{this.props.name}
</li>
)
}
handleClick(id){
// console.log(this.props.history)
this.props.history.push(`/detail/${id}`)
// this.props.history.push 跳转页面
// this.props.history.match 获取参数
// this.props.history.location 获取当前路由
}
}
export default withRouter(FilmItem)//****
路由懒加载
import React from 'react'
import {Route,Routes,Navigate} from 'react-router-dom'
// import Cinema from '../views/Cinema';
export default function MRouter () {
return (
<Routes>
{/* <Route path="/cinemas" element={<Cinema />} /> */}
//定义规则
<Route path="/cinemas" element={LazyLoad("Cinema")} />
</Routes>
)
}
//懒加载函数
const LazyLoad = (path) => {
const Comp = React.lazy(() => import(`../views/${path}`))
return ( //必须要借助React.Suspense
<React.Suspense fallback={<>加载中...</>}>
<Comp />
</React.Suspense>
)
}
useRoutes钩子配置路由
像vue一样配置路由 src/router/index.js
import React from 'react'
import {useRoutes} from 'react-router-dom'
import Redirect from '../components/Redirect';
export default function MRouter() {
const element = useRoutes([
{
path:"/films",
//懒加载
element:LazyLoad("Film"),
//子路由
children:[
{
path:"",
element:<Navigate to="/films/nowplaying"/>
}
]
},
{
path:"/center",
//路由拦截
element:<AuthComponent>
{LazyLoad("Center")}
</AuthComponent>
},
{
path:"/",
element:<Navigate to="/films"/> //默认路由
},
{
path:"*",
element:LazyLoad("NotFound") //404
}
])
//将组件路由规则返回
return (
element
)
}
//路由拦截组件的封装
function AuthComponent({children}){}
//路由懒加载的封装
const LazyLoad = (path)=>{}
