useRouters 的使用
-
动态地配置路由
-
接收一个路由数组,用匹配到的路由来渲染相应的组件
-
在应用的生命周期中更改路由更容易
-
用
Routes
包裹Route
组件(react-router v6
强制要求)
文件结构
-
router
index.tsx
:存放路由数组
import { message } from "antd"; import { useEffect } from "react"; import { useSelector } from "react-redux"; import { matchRoutes, useLocation, useNavigate } from "react-router-dom"; import { routers } from "./index"; const AuthRoute = ({ children, auth }: any) => { const navigate = useNavigate(); const token = localStorage.getItem("blogToken") || ""; const loginState = useSelector((state: any) => state.public.loginState); const mathchs = matchRoutes(routers, location); const isExist = mathchs?.some((item) => item.pathname == location.pathname); useEffect(() => { if (token == "" && auth) { message.error("token 过期,请重新登录!"); navigate("/login"); } // 这里判断条件是:token 存在并且是匹配到路由并且是已经登录的状态 if (token && isExist && loginState == "login") { // 如果你已经登录了,但是你通过浏览器里直接访问login的话不允许直接跳转到login路由,必须通过logout来控制退出登录或者是token过期返回登录界面 if (location.pathname == "/" || location.pathname == "/login") { navigate("/home"); } else { // 如果是其他路由就跳到其他的路由 navigate(location.pathname); } } }, [token, location.pathname]); return children; }; export default AuthRoute;
AuthRouter
:路由权限控制
import { message } from "antd"; import { useEffect } from "react"; import { useSelector } from "react-redux"; import { matchRoutes, useLocation, useNavigate } from "react-router-dom"; import { routers } from "./index"; const AuthRoute = ({ children, auth }: any) => { const navigate = useNavigate(); const token = localStorage.getItem("blogToken") || ""; const loginState = useSelector((state: any) => state.public.loginState); const mathchs = matchRoutes(routers, location); const isExist = mathchs?.some((item) => item.pathname == location.pathname); useEffect(() => { if (token == "" && auth) { message.error("token 过期,请重新登录!"); navigate("/login"); } // 这里判断条件是:token 存在并且是匹配到路由并且是已经登录的状态 if (token && isExist && loginState == "login") { // 如果你已经登录了,但是你通过浏览器里直接访问login的话不允许直接跳转到login路由,必须通过logout来控制退出登录或者是token过期返回登录界面 if (location.pathname == "/" || location.pathname == "/login") { navigate("/home"); } else { // 如果是其他路由就跳到其他的路由 navigate(location.pathname); } } }, [token, location.pathname]); return children; }; export default AuthRoute;
-
App.tsx
import { ReactNode, useCallback, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import {
Route,
Routes,
} from "react-router-dom";
import { RouteConfig, routers } from "./router";
import AuthRoute from "./router/AuthRoute";
const App = () => {
const loginState = useSelector((state: any) => state.public.loginState);
// 处理我们的routers
const RouteAuthFun = (
(routeList: RouteConfig[]) => {
return routeList.map(
(item: {
path: string;
auth: boolean;
element: ReactNode;
children?: any;
}) => {
return (
<Route
path={item.path}
element={
<AuthRoute auth={item.auth} key={item.path}>
{item.element}
</AuthRoute>
}
key={item.path}
>
{/* 递归调用,因为可能存在多级的路由 */}
{item?.children && RouteAuthFun(item.children)}
</Route>
);
}
);
}
);
return <Routes>{RouteAuthFun(routers)}</Routes>;
};
export default App;