react 路由V6 路由跳转传参、嵌套路由、路由映射、路由懒加
2023-05-04 本文已影响0人
暴躁程序员
一、 React-Router V6 基础环境搭建
- 安装依赖
yarn add react-router-dom@6
- 在 index.js 中引入并使用路由模块包裹根组件
路由模式:HashRouter、BrowserRouter
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
二、 React-Router V6 路由跳转、路由重定向、定义 404
- 新建路由组件
src/pages/Home、src/pages/Mine、src/pages/Page404
// Home 页面
import React from "react";
function Home() {
return (
<>
<div>Home</div>
</>
);
}
export default Home;
// Mine 页面
import React from "react";
function Mine() {
return (
<>
<div>Mine</div>
</>
);
}
export default Mine;
// Page404 页面
import React from "react";
function Page404() {
return (
<>
<div>404</div>
</>
);
}
export default Page404;
- 在 src/App.js 组件中,实现路由跳转、路由重定向、404 页面
import {
Routes,
Route,
Link,
NavLink,
Navigate,
useNavigate,
} from "react-router-dom";
import Home from "./pages/Home";
import Mine from "./pages/Mine";
import Page404 from "./pages/Page404";
function App() {
const navigate = useNavigate();
return (
<>
<div>
<h1>link 声明式路由跳转</h1>
<Link to="/home"> go Home </Link> | <Link to="/Mine"> go Mine </Link>
</div>
<hr />
<div>
<h1>NavLink 声明式路由跳转,动态添加.active</h1>
<NavLink to="/home"> go Home </NavLink> |<NavLink to="/Mine"> go Mine </NavLink>
</div>
<hr />
<div>
<h1>编程式路由跳转</h1>
<div
onClick={() => {
navigate("/home");
}}
>
go Home
</div>
<div
onClick={() => {
navigate("/mine");
}}
>
go Mine
</div>
</div>
<hr />
<div>
<h1>路由出口</h1>
{/* 路由出口 */}
<Routes>
{/* 路由重定向 */}
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/Mine" element={<Mine />} />
{/* 未定义路由出口 404 */}
<Route path="*" element={<Page404 />} />
</Routes>
</div>
</>
);
}
export default App;
三、 React-Router V6 路由参数传递
1. params 参数
特点:参数只能是字符串,显示在地址栏上,刷新页面后参数不丢失
- 在 src/App.js 中传递参数
import {
Routes,
Route,
Link,
NavLink,
Navigate,
useNavigate,
} from "react-router-dom";
import Home from "./pages/Home";
import Mine from "./pages/Mine";
import Page404 from "./pages/Page404";
function App() {
const navigate = useNavigate();
return (
<>
<div>
<h1>link 路由跳转</h1>
<Link to="/home"> go Home </Link> |<Link to="/Mine/100/小米"> go Mine </Link>
</div>
<hr />
<div>
<h1>NavLink 路由跳转,动态添加.active</h1>
<NavLink to="/home"> go Home </NavLink> |<NavLink to="/Mine/100/小米"> go Mine </NavLink>
</div>
<hr />
<div>
<h1>编程式路由跳转</h1>
<div
onClick={() => {
navigate("/home");
}}
>
go Home
</div>
<div
onClick={() => {
navigate("/mine/99/小编");
}}
>
go Mine
</div>
</div>
<hr />
<div>
<h1>路由出口</h1>
<Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/Mine/:id/:name" element={<Mine />} />
<Route path="*" element={<Page404 />} />
</Routes>
</div>
</>
);
}
export default App;
- 在 src/pages/Mine.js 中接收参数
在函数组件中使用 useParams() 获取参数
import React from "react";
import { useParams } from "react-router-dom";
function Mine() {
const { id, name } = useParams();
return (
<>
<div>Mine</div>
<div>{id}</div>
<div>{name}</div>
</>
);
}
export default Mine;
2. search 参数
特点:显示在地址栏上,刷新页面后参数不丢失
- 在 src/App.js 中传递参数
import {
Routes,
Route,
Link,
NavLink,
Navigate,
useNavigate,
} from "react-router-dom";
import Home from "./pages/Home";
import Mine from "./pages/Mine";
import Page404 from "./pages/Page404";
function App() {
const navigate = useNavigate();
return (
<>
<div>
<h1>link 路由跳转</h1>
<Link to="/home"> go Home </Link> |<Link to="/Mine?id=100&name=小米"> go Mine </Link>
</div>
<hr />
<div>
<h1>NavLink 路由跳转,动态添加.active</h1>
<NavLink to="/home"> go Home </NavLink> |<NavLink to="/Mine?id=100&name=小米"> go Mine </NavLink>
</div>
<hr />
<div>
<h1>编程式路由跳转</h1>
<div
onClick={() => {
navigate("/home");
}}
>
go Home
</div>
<div
onClick={() => {
navigate("/mine?id=99&name=小编");
}}
>
go Mine
</div>
</div>
<hr />
<div>
<h1>路由出口</h1>
<Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/Mine" element={<Mine />} />
<Route path="*" element={<Page404 />} />
</Routes>
</div>
</>
);
}
export default App;
- 在 src/pages/Mine.js 中接收参数
在函数组件中使用 useSearchParams() 获取参数
import React from "react";
import { useSearchParams } from "react-router-dom";
function Mine() {
const [search] = useSearchParams();
let id = search.get("id");
let name = search.get("name");
return (
<>
<div>Mine</div>
<div>{id}</div>
<div>{name}</div>
</>
);
}
export default Mine;
3. state 参数
特点:参数可以是对象,不显示在地址栏上,刷新页面后参数不丢失(HashRouter 模式,参数会丢失)
- 在 src/App.js 中传递参数
import {
Routes,
Route,
Link,
NavLink,
Navigate,
useNavigate,
} from "react-router-dom";
import Home from "./pages/Home";
import Mine from "./pages/Mine";
import Page404 from "./pages/Page404";
function App() {
const navigate = useNavigate();
return (
<>
<div>
<h1>link 路由跳转</h1>
<Link to="/home"> go Home </Link> |<Link
to="/Mine"
state={{ id: 100, name: "小米" }}
>
go Mine
</Link>
</div>
<hr />
<div>
<h1>NavLink 路由跳转,动态添加.active</h1>
<NavLink to="/home">go Home</NavLink>|<NavLink
to="/Mine"
state={{ id: 100, name: "小米" }}
>
go Mine
</NavLink>
</div>
<hr />
<div>
<h1>编程式路由跳转</h1>
<div
onClick={() => {
navigate("/home");
}}
>
go Home
</div>
<div
onClick={() => {
navigate("/mine", {
state: { id: 99, name: "小编" },
});
}}
>
go Mine
</div>
</div>
<hr />
<div>
<h1>路由出口</h1>
<Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/Mine" element={<Mine />} />
<Route path="*" element={<Page404 />} />
</Routes>
</div>
</>
);
}
export default App;
- 在 src/pages/Mine.js 中接收参数
在函数组件中使用 useLocation() 获取参数
import React from "react";
import { useLocation } from "react-router-dom";
function Mine() {
const { state } = useLocation();
return (
<>
<div>Mine</div>
<div>{state.id}</div>
<div>{state.name}</div>
</>
);
}
export default Mine;
四、 React-Router V6 嵌套路由
- 新建嵌套路由子页面
src/pages/V1.js 和 src/pages/V2.js
import React from "react";
function V1() {
return (
<>
<div>V1</div>
</>
);
}
export default V1;
import React from "react";
function V2() {
return (
<>
<div>V2</div>
</>
);
}
export default V2;
- 在 src/App.js 中定义嵌套路由和路由跳转
import { Routes, Route, Link, Navigate } from "react-router-dom";
import Home from "./pages/Home";
import Mine from "./pages/Mine";
import Page404 from "./pages/Page404";
import V1 from "./pages/V1";
import V2 from "./pages/V2";
function App() {
return (
<>
<div>
<h1>link 声明式路由跳转</h1>
<Link to="/home"> go Home </Link> | <Link to="/mine"> go Mine </Link>|<Link to="/mine/v1">
go Mine V1
</Link> |<Link to="/mine/v2"> go Mine V2 </Link>
</div>
<hr />
<div>
<h1>路由出口</h1>
<Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/mine" element={<Mine />}>
<Route path="v1" element={<V1 />} />
<Route path="v2" element={<V2 />} />
</Route>
<Route path="*" element={<Page404 />} />
</Routes>
</div>
</>
);
}
export default App;
- 在 src/pages/Mine.js 中定义嵌套子路由出口
嵌套路由出口需要使用 Outlet 占位
import React from "react";
import { Outlet } from "react-router-dom";
function Mine() {
return (
<>
<div>Mine</div>
<hr />
{/* 嵌套路由出口 */}
<Outlet />
</>
);
}
export default Mine;
五、 React-Router V6 路由关系映射配置
- 新建 src\routes\index.js 路由关系映射文件
import { Navigate } from "react-router-dom";
import Home from "../pages/Home";
import Mine from "../pages/Mine";
import Page404 from "../pages/Page404";
import V1 from "../pages/V1";
import V2 from "../pages/V2";
const routes = [
{
path: "/",
element: <Navigate to="/home" />,
},
{
path: "/home",
element: <Home />,
},
{
path: "/mine",
element: <Mine />,
children: [
{
path: "v1",
element: <V1 />,
},
{
path: "v2",
element: <V2 />,
},
],
},
{
path: "*",
element: <Page404 />,
},
];
export default routes;
- 在 src/App.js 中通过
useRoutes(routes)
加载路由映射配置
import { Link, useRoutes } from "react-router-dom";
import routes from "./routes";
function App() {
return (
<>
<div>
<h1>link 导航跳转</h1>
<Link to="/home"> go Home </Link> | <Link to="/mine"> go Mine </Link>|<Link to="/mine/v1">
go Mine V1
</Link> |<Link to="/mine/v2"> go Mine V2 </Link>
</div>
<hr />
<div>
<h1>路由出口</h1>
<div>{useRoutes(routes)}</div>
</div>
</>
);
}
export default App;
- 在 src/pages/Mine.js 中定义嵌套子路由出口
嵌套路由出口需要使用 Outlet 占位
import React from "react";
import { Outlet } from "react-router-dom";
function Mine() {
return (
<>
<div>Mine</div>
<hr />
{/* 嵌套路由出口 */}
<Outlet />
</>
);
}
export default Mine;
六、 React-Router V6 路由懒加载
1. 方式一:在组件中实现路由懒加载
- 在 src/App.js 中通过
React.lazy()
加载路由组件,使用Suspense
包裹路由出口
import React, { Suspense } from "react";
import { Routes, Route, Link, Navigate } from "react-router-dom";
import Home from "./pages/Home";
const Mine = React.lazy(() => import("./pages/Mine"));
const Page404 = React.lazy(() => import("./pages/Page404"));
const V1 = React.lazy(() => import("./pages/V1"));
const V2 = React.lazy(() => import("./pages/V2"));
function App() {
return (
<>
<div>
<h1>link 声明式路由跳转</h1>
<Link to="/home"> go Home </Link> | <Link to="/mine"> go Mine </Link>|<Link to="/mine/v1">
go Mine V1
</Link> |<Link to="/mine/v2"> go Mine V2 </Link>
</div>
<hr />
<div>
<h1>路由出口</h1>
<Suspense>
<Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />} />
<Route path="/mine" element={<Mine />}>
<Route path="v1" element={<V1 />} />
<Route path="v2" element={<V2 />} />
</Route>
<Route path="*" element={<Page404 />} />
</Routes>
</Suspense>
</div>
</>
);
}
export default App;
2. 方式二:在配置路由映射文件中实现路由懒加载
- 在 src\routes\index.js 中通过
React.lazy()
加载路由组件,再使用Suspense
包裹加载后的路由组件
import React, { Suspense } from "react";
import { Navigate } from "react-router-dom";
import Home from "../pages/Home"; // 同步
const Mine = React.lazy(() => import("../pages/Mine"));
const Page404 = React.lazy(() => import("../pages/Page404"));
const V1 = React.lazy(() => import("../pages/V1"));
const V2 = React.lazy(() => import("../pages/V2"));
const routes = [
{
path: "/",
element: <Navigate to="/home" />,
},
{
path: "/home",
element: <Home />,
},
{
path: "/mine",
element: (
<Suspense>
<Mine />
</Suspense>
),
children: [
{
path: "v1",
element: (
<Suspense>
<V1 />
</Suspense>
),
},
{
path: "v2",
element: (
<Suspense>
<V2 />
</Suspense>
),
},
],
},
{
path: "*",
element: (
<Suspense>
<Page404 />
</Suspense>
),
},
];
export default routes;