熟悉的Vue的朋友都知道,Vue-router中有大量钩子函数,包含组件声明周期的,路由的等,但在react中,没有路由钩子函数,需要自己去实现,最简单方法就是使用高阶组件,那什么是高阶组件呢?
高阶组件(HOC)是React中的一个概念,它是一个接受一个组件并返回一个新组件的函数;
实现的方式有好多,还可以使用route组件的render属性,但是在6版本中,采用路由表配置路由,就不太好用;
let routes = [
{
path: '/login',
element: <Login />
},
{
path: '/index',
element: <Layout />,
children: [
{
path: 'mor',
element: <Mor />
},
{
path: 'wan',
element: <Wan />,
children: [
{
path: 'context',
element: <Mess />,
children: [
// params参数格式
// {
// path: 'detail/:id/:title/:content',
// element: <Detail />
// }
// search,state参数-不需要占位
{
path: 'detail',
element: <Detail />
}
]
}
]
},
]
},
{
path: '/',
element: <Navigate to="/index" />
},
{ path: '*', element: <NotFound /> },
]
export default routes
高阶组件实现过程图下:
import { useNavigate, useLocation } from 'react-router-dom';
import { useEffect } from 'react';
import { getToken } from "./utils/token.js";
function withProtectedRoute(WrappedComponent) {
return function ProtectedRoute(props) {
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
const token = getToken();
if (token) {
if (location.pathname === '/login') {
navigate('/', { replace: true });
}
} else {
navigate('/login', { replace: true });
}
}, [location.pathname, navigate]);
return <WrappedComponent {...props} />;
};
}
export default withProtectedRoute
然后将App根组件传入,就可以实现全局守卫了
import React from 'react'
import { useRoutes } from "react-router-dom";
import routes from "./routes";
import withProtectedRoute from "./permission";
import './App.css';
function App() {
// 同时支持路由表形式
const elementRouter = useRoutes(routes)
return (
<div className="App">
{/* 注册路由出口
* 在6版本中switch单一匹配采用Routes代替
*/}
{elementRouter}
</div>
);
}
{/* 高阶组件实现全局路由守卫 */ }
export default withProtectedRoute(App)