React:动态配置嵌套路由及路由守卫
遇到的问题
最近在学习React时发现,React的页面路由有点简陋。React 原生没有提供类似Vue所使用的路由管理库,虽然其<Route>组件支持如onEnter和onLeave等路由钩子函数,但是在配置复杂前端系统时会显得比较臃肿。因此,在参考了大量网上的写法以及React route这部分相关的源码后,自己动手搭了一个支持动态配置、支持路由守卫的组件。
路由表配置文件
这个文件主要用于组织前端页面组件以及其跳转关系
// routerConfig.js
const RouterConfig = [
{
path: '/login',
exact: true,
component: Login
},
{
path: '/',
component: Main,
routes: [
{
path: '/test',
exact: true,
requireAuth: true,
component: TestModule
},
]
},
]
export default RouterConfig
嵌套路由组件
将某一层的路由配置全部转成<Route>
标签,同时通过重写 render 函数控制标签渲染内容(路由守卫)
// routerGuard.jsx
import React from "react"
import { Route, Redirect, Switch } from "react-router-dom"
const LOGIN_PATH = "/login"
const checkLoginStatus = () => true
export const RenderRoutes = function({ routes }) {
return (
<Switch>
{ routes.map((route, i) => (
<Route
key={route.key || i}
path={route.path}
exact={route.exact}
strict={route.strict}
render={props => {
const isLoggedIn = checkLoginStatus()
const pathname = props.location.pathname
if (isLoggedIn || pathname === LOGIN_PATH) {
if (!route.requireAuth) {
return route.render ?
route.render({ ...props, route: route}) :
route.component && <route.component {...props} route={route} />
} else {
// CHECK AUTH
return null
}
} else {
return <Redirect to={LOGIN_PATH} />
}
}}
/>
))}
</Switch>
)
}
使用方式
App.jsx:前端页面总入口
Main.jsx:前端页面框架
TestModule.jsx:嵌套在Main下的功能页面
// App.jsx
import { BrowserRouter } from "react-router-dom";
import { RenderRoutes } from "routerGuard"
import RouterConfig from "routerConfig"
export default function App() {
return (
<BrowserRouter>
<div>
<RenderRoutes routes={RouterConfig} />
</div>
</BrowserRouter>
);
}
// Main.jsx
import { RenderRoutes } from "routerGuard"
export const Main = function Main(props) {
return (
<div>
{ RenderRoutes(props.route) }
</div>
);
}
// TestModule.jsx
export const TestModule = function TestModule(props) {
return (
<div>test</div>
);
}