react-router-V6
一、路由模式
react 路由有两种模式,
HashRouter:hash 模式,带#号
BrowserRouter: history 模式,不带#号,这种模式需要后端配合。
导入这两个组件中的一个,包裹根组件
import React from "react"
import ReactDOM from "react-dom/client"
// as 是别名 相当于将HashRouter 重命名为 RouterMode
import { HashRouter as RouterMode } from "react-router-dom"
import App from "./App"
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(
<RouterMode>
<App />
</RouterMode>
)
二、一级路由
import React from "react"
import { Routes, Route } from "react-router-dom"
import PageA from "./pages/PageA"
import PageB from "./pages/PageB"
import PageC from "./pages/PageC"
const App = () => {
return (
<Routes>
{/* 默认路由 需要复制一份单独写哦 */}
<Route index element={<PageA />} />
<Route path="/pagea" element={<PageA />} />
<Route path="/pageb" element={<PageB />} />
<Route path="/pagec" element={<PageC />} />
</Routes>
)
}
export default App
三、默认路由
{/* 默认路由 需要复制一份单独写哦 */}
<Route index element={<PageA />} />
<Route path="/pagea" element={<PageA />} />
四、路由重定向
方式一:使用 Navigate 组件
<Route path="*" element={<Navigate to="/pagea" />} />
方式二:自己封装一个组件:Redirect
import React, { useEffect } from "react"
import { useNavigate } from "react-router-dom"
const Redirect = ({ to }) => {
const navigate = useNavigate()
useEffect(() => {
navigate(to, { replace: true })
})
return null
}
export default Redirect
<Route path="*" element={<Redirect to="/pagea" />} />
五、404-NotFound
NotFound 需要自己书写
<Route path="*" element={<NotFound />} />
六、嵌套路由
<Route path="/pagea" element={<PageA />}>
<Route path="pagea-sub1" element={<PageASub1 />}></Route>
<Route path="pagea-sub2" element={<PageASub2 />}></Route>
</Route>
pageA中的配置
import React from "react"
import { Outlet } from "react-router-dom"
const PageA = () => {
return (
<div>
PageA
<Outlet></Outlet> // 子组件通过这个组件输出到这个位置
</div>
)
}
export default PageA
七、声明式导航与编程式导航
1. 声明式导航
该组件 自带 active 类名,直接设置,即可高亮显示。
<NavLink to="/pagec">PageC</NavLink>
下面这种方式,可以自定义高亮的类名。推荐
<NavLink
to="/pageb"
className={({ isActive }) => (isActive ? "zrsactive" : "")}
>
PageB
</NavLink>
2. 编程式导航
import {useNavigate } from "react-router-dom"
const navigate = useNavigate()
push的方式:压栈
<button
onClick={() => {
navigate("/pageb")
}}
>
PageB
</button>
replace的方式:替换当前路由
<button
onClick={() => {
navigate("/pagec", { replace: true })
}}
>
PageC
</button>
八、路由传参
1. 动态路由
动态路由设置,冒号必须写,但是冒号后面的东西可以自定义
<Route path="/pagec/:myId" element={<PageC />} />
<button
onClick={() => {
navigate(`/pagec/${id}`, { replace: true })
}}
>
PageC
</button>
多层级的传参方式
// 可以多层嵌套
<Route path="/pagec/:myId/:userName" element={<PageC />} />
<button
onClick={() => {
navigate(`/pagec/${id}/${name}`, { replace: true })
}}
>
PageC
</button>
获取参数
import React from "react"
import { useParams } from "react-router-dom"
const PageC = () => {
const params = useParams()
console.log(params)
return (
<div>
PageC
<h1>{params.myId}</h1>
</div>
)
}
export default PageC
2. query(URLSearch)的方式传参
<button
onClick={() => {
navigate(`/pagec?id=${filmId}`, { replace: true })
}}
>
PageC
</button>
获取参数
import React from "react"
import { useSearchParams } from "react-router-dom"
const PageC = () => {
const [searchParams, setSearchParams] = useSearchParams()
// 通过这种方式获取参数
console.log(searchParams.get("id"))
return (
<div>
PageC
<h1>{searchParams.get("id")}</h1>
// 通过 setSearchParams 去改变参数
<button
onClick={() => {
setSearchParams({ id: 45678 })
}}
>
改变参数
</button>
</div>
)
}
九、路由拦截
创建鉴权组件
import React from "react"
import { Navigate } from "react-router-dom"
const AuthComponent = ({ children }) => {
let token = sessionStorage.getItem("TOKEN")
return token ? children : <Navigate to="/login" />
}
export default AuthComponent
使用鉴权组件包裹
<Route
path="/pageb"
element={
<AuthComponent>
<PageB />
</AuthComponent>
}
/>
WithRouter 组件封装
该组件主要是v6版本配合类组件使用,给类组件添加路由跳转的方法。
import React from "react"
import { useNavigate, useLocation, useParams } from "react-router-dom"
const WithRouter = (Component) => {
return (props) => {
const navigate = useNavigate()
const params = useParams()
const location = useLocation()
return <Component {...props} history={(navigate, params, location)} />
}
}
export default WithRouter
十、路由懒加载
import React from "react"
const LazyLoad = (path) => {
const Component = React.lazy(() => import(`../pages/${path}`))
return (
<React.Suspense fallback={<h2>加载中...</h2>}>
<Component />
</React.Suspense>
)
}
export default LazyLoad
<Route path="/pagec/:myId" element={LazyLoad("PageC")} />
十一、useRoutes 钩子配置路由
useRoutes 只需要传入一个数组,数组按照下面的方法配置,即可自动生成路由配置表。
import { Navigate, useRoutes } from "react-router-dom"
import LazyLoad from "./components/LazyLoad"
import Redirect from "./components/Redirect"
const App = () => {
return useRoutes([
{
path: "/login",
element: LazyLoad("Login")
},
{
path: "/pagea",
element: LazyLoad("PageA"),
children: [
{
path: "",
// element: <Navigate to="/pagea/pageasub1" />
element: <Redirect to="/pagea/pageasub1" />
},
{
path: "pageasub1",
element: LazyLoad("pageaFiles/PageASub1")
}
]
},
{
path: "/pageb",
element: LazyLoad("PageB")
},
{
path: "/pagec",
element: LazyLoad("PageC")
}
])
}
export default App