React 基礎(chǔ)鞏固(四十一)——手動(dòng)路由跳轉(zhuǎn)、參數(shù)傳遞及路由配置
一、實(shí)現(xiàn)手動(dòng)跳轉(zhuǎn)路由
- 利用 useNavigate 封裝一個(gè) withRouter(hoc/with_router.js)
import { useNavigate } from "react-router-dom";
// 封裝一個(gè)高階組件
function withRouter(WrapperComponent) {
return function (props) {
const navigate = useNavigate();
const router = { navigate };
return <WrapperComponent {...props} router={router} />;
};
}
export default withRouter;
- 添加到hoc/index.js文件中
import withRouter from "./with_router";
export { withRouter };
- 利用withRouter,攔截Home組件,實(shí)現(xiàn)手動(dòng)跳轉(zhuǎn)路由
import React, { PureComponent } from "react";
import { Link, Outlet } from "react-router-dom";
import { withRouter } from "../hoc";
export class Home extends PureComponent {
navigateTo(path) {
const { navigate } = this.props.router;
navigate(path);
}
render() {
return (
<div>
<h1>Home</h1>
<div className="nav">
<Link to="/home/recommend">推薦</Link>
<Link to="/home/ranking">排行榜</Link>
<button onClick={(e) => this.navigateTo("/home/songmenu")}>
歌單
</button>
</div>
{/* 占位組件 */}
<Outlet />
</div>
);
}
}
export default withRouter(Home);
二、路由參數(shù)傳遞
路由參數(shù)傳遞包括:1.動(dòng)態(tài)路由傳參;2.查詢字符串傳參
改造withRouter,通過useParams()
和useSearchParams()
來接收兩種參數(shù)傳遞:
import {
useLocation,
useNavigate,
useParams,
useSearchParams,
} from "react-router-dom";
// 封裝一個(gè)高階組件
function withRouter(WrapperComponent) {
return function (props) {
// 1.導(dǎo)航
const navigate = useNavigate();
// 2.動(dòng)態(tài)路由參數(shù)
const params = useParams();
// 3.查詢字符串的參數(shù):/user?name=test&age=18
const location = useLocation();
const [searchParams] = useSearchParams();
const query = Object.fromEntries(searchParams)
console.log(query);
const router = { navigate, params, location, query };
return <WrapperComponent {...props} router={router} />;
};
}
export default withRouter;
在界面中,通過params來接收(Detail.js):
import React, { PureComponent } from "react";
import { withRouter } from "../hoc";
export class Detail extends PureComponent {
render() {
const { router } = this.props;
const { params } = router;
return (
<div>
<h2>Detail</h2>
<h2>id:{params.id}</h2>
</div>
);
}
}
export default withRouter(Detail);
通過 query 來接收(User.jsx):
import React, { PureComponent } from "react";
import { withRouter } from "../hoc";
export class User extends PureComponent {
render() {
const { router } = this.props;
const { query } = router;
return (
<div>
<h1>
用戶:{query.name} - {query.age}
</h1>
</div>
);
}
}
export default withRouter(User);
三、路由配置文件
當(dāng)前App.jsx文件中,包含Routes相關(guān)信息,過于臃腫,我們可以將Routes通過配置的形式進(jìn)行引入。
構(gòu)建router/index.js,將所有的路由配置在此處:
import Home from "../pages/Home";
import About from "../pages/About";
import Login from "../pages/Login";
import NotFound from "../pages/NotFound";
import HomeRecommend from "../pages/HomeRecommend";
import HomeRanking from "../pages/HomeRanking";
import Category from "../pages/Category";
import Order from "../pages/Order";
import HomeSangMenu from "../pages/HomeSangMenu";
import Detail from "../pages/Detail";
import User from "../pages/User";
import { Navigate } from "react-router-dom";
const routes = [
{
path: "/",
element: <Navigate to="/home" />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "/home",
element: <Navigate to="/home/recommend" />,
},
{
path: "/home/recommend",
element: <HomeRecommend />,
},
{
path: "/home/ranking",
element: <HomeRanking />,
},
{
path: "/home/sangmenu",
element: <HomeSangMenu />,
},
],
},
{
path: "/about",
element: <About />,
},
{
path: "/login",
element: <Login />,
},
{
path: "/category",
element: <Category />,
},
{
path: "/order",
element: <Order />,
},
{
path: "/detail",
element: <Detail />,
},
{
path: "/user",
element: <User />,
},
{
path: "*",
element: <NotFound />,
},
];
export default routes;
改寫App.jsx,通過useRoutes(routes)
引入路由:
import React from "react";
import {
Link,
NavLink,
useNavigate,
useRoutes,
} from "react-router-dom";
import "./style.css";
// import Home from "./pages/Home";
// import About from "./pages/About";
// import Login from "./pages/Login";
// import NotFound from "./pages/NotFound";
// import HomeRecommend from "./pages/HomeRecommend";
// import HomeRanking from "./pages/HomeRanking";
// import Category from "./pages/Category";
// import Order from "./pages/Order";
// import HomeSangMenu from "./pages/HomeSangMenu";
// import Detail from "./pages/Detail";
// import User from "./pages/User";
import routes from "./router";
export function App(props) {
const navigate = useNavigate();
function navigateTo(path) {
console.log(path);
navigate(path);
}
return (
<div className="app">
<div className="header">
<span>header</span>
<div className="nav">
<NavLink to="/home">首頁</NavLink>
<NavLink to="/about">關(guān)于</NavLink>
<NavLink to="/login">登陸</NavLink>
<button onClick={(e) => navigateTo("/category")}>分類</button>
<span onClick={(e) => navigateTo("/order ")}>訂單</span>
<Link to="/user?name=test&age=18">用戶</Link>
</div>
<hr />
</div>
<div className="content">
{/* 映射關(guān)系: path => Component */}
{/* <Routes>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<Home />}>
<Route path="/home" element={<Navigate to="/home/recommend" />} />
<Route path="/home/recommend" element={<HomeRecommend />} />
<Route path="/home/ranking" element={<HomeRanking />} />
<Route path="/home/songmenu" element={<HomeSangMenu />} />
</Route>
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/category" element={<Category />} />
<Route path="/order" element={<Order />} />
<Route path="/detail/:id" element={<Detail />} />
<Route path="/user" element={<User />} />
<Route path="*" element={<NotFound />} />
</Routes> */}
{useRoutes(routes)}
</div>
<div className="footer">Footer</div>
</div>
);
}
export default App;
查看運(yùn)行效果,與之前保持一致:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-AByH8LHr-1690721021332)(https://gitee.com/outmanm78/markdown-image/raw/master/img/202307302029353.png)]
雖然成功抽離了路由配置信息,但是目前的方式,會(huì)導(dǎo)致路由統(tǒng)一打包,沒有分包處理。我們可以進(jìn)行改造一下,針對(duì)部分配置進(jìn)行分包處理,實(shí)現(xiàn)路由懶加載:
import React from "react";
import Home from "../pages/Home";
// import About from "../pages/About";
// import Login from "../pages/Login";
import NotFound from "../pages/NotFound";
import HomeRecommend from "../pages/HomeRecommend";
import HomeRanking from "../pages/HomeRanking";
import Category from "../pages/Category";
import Order from "../pages/Order";
import HomeSangMenu from "../pages/HomeSangMenu";
import Detail from "../pages/Detail";
import User from "../pages/User";
import { Navigate } from "react-router-dom";
// 通過React.lazy實(shí)現(xiàn)About和Login界面的路由懶加載
const About = React.lazy(() => import("../pages/About"));
const Login = React.lazy(() => import("../pages/Login"));
在src/index.js中,用Suspense
對(duì)App進(jìn)行包裹,實(shí)現(xiàn)對(duì)分包加載的等待:
import React, { Suspense } from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { HashRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<HashRouter>
<Suspense fallback={<h3>Loading...</h3>}>
<App />
</Suspense>
</HashRouter>
</React.StrictMode>
);
查看效果,與之前保持一致,懶加載實(shí)現(xiàn)成功:文章來源:http://www.zghlxwxcb.cn/news/detail-619377.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-619377.html
到了這里,關(guān)于【前端知識(shí)】React 基礎(chǔ)鞏固(四十一)——手動(dòng)路由跳轉(zhuǎn)、參數(shù)傳遞及路由配置的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!