React Router V6实现路由守卫
先上代码:
入口文件
import React from react; import ReactDOM from react-dom/client; import ./index.css; import reportWebVitals from ./reportWebVitals; import { BrowserRouter } from react-router-dom import AppRouter from ./router/routeNav; const root = ReactDOM.createRoot( document.getElementById(root) as HTMLElement ); root.render( <React.StrictMode> <BrowserRouter> <AppRouter /> </BrowserRouter> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
AppRouter.js文件
import { Route,Routes, useLocation, Navigate } from react-router-dom import Login from ../page/login/login; import Index from ../page/index/index; import Register from ../page/register/register; import ErrPage from ../page/ErrPage/errPage; import MySpace from ../component/my_space/mySpace; import H5Template from ../component/h5_template/h5Template; import { ReactNode } from react; const AppRouter = () => { const location = useLocation(); const { pathname } = location; const routes = [ { path: /, auth: false, component: <Navigate to=/index />, }, { path: /index, auth: false, component: <Index />, child: [ { path: /index/myspace, auth: true, component: <MySpace /> }, { path: /index/h5template, auth: false, component: <H5Template /> } ] }, { path: /login, auth: false, component: <Login /> }, { path: /register, auth: false, component: <Register /> }, { path: /errPage, auth: false, component: <ErrPage /> }, { path: /*, auth: false, component: <Navigate to=/errPage replace={true}></Navigate> } ] const isLogin = false; //请求页面路径需要验证 && 没有登录 -> 跳转登录页 , 后续考虑登录后是否自动跳转被拦截路径 const RouteNav = (param: any) => { return ( param.map((item: {path: string,auth: boolean,component: ReactNode, child?: any}) => { return ( <Route path={item.path} element={item.path === pathname && item.auth && !isLogin ? <Navigate to=/login replace={true}></Navigate> : item.component} key={item.path}> { item?.child && RouteNav(item.child) } </Route> ) }) ) } return ( <Routes> { RouteNav(routes) } </Routes> ) } export default AppRouter;
解释:AppRoute文件动态生成了路由,该文件最后会返回如下形式的代码给入口文件。
<Routes> <Route> <Route></Route> .... </Route> ... </Routes>
函数RouteNav会根据routes递归生成路由表,利用useLoation可以拿到用户当前想要访问的页面路径。如果用户访问的路径是/则利用routes的第一条规则,让用户重定向至index页。如果用户访问的路径不存在与路右表里面,则由最后一条规则重定向至错误页。如果用户访问的页面需要登录,但是当前未登录,则在创建路由过程中,利用如下判断,重定向至登录页。
element={item.path === pathname && item.auth && !isLogin ? <Navigate to=/login replace={true}></Navigate> : item.component}
这样一个简单的基于React Router V6的路由守卫就做好了