写点什么

面向企业级应用的 React 路由管理体系:react-router-manage 实践

作者:shinpei
  • 2025-04-14
    浙江
  • 本文字数:6017 字

    阅读完需:约 20 分钟

面向企业级应用的React路由管理体系:react-router-manage实践

当今复杂的企业级前端应用开发中,尤其是中后台应用中,路由管理已不再是简单的页面切换,而是演变为一套完整的状态管理、权限控制、导航构建和用户体验优化的综合解决方案。react-router-manage 应运而生,它在 react-router v6 的基础上构建了一个更高维度的路由管理生态,为开发者提供了一种优雅而高效的前端架构范式。


该库在网易云商多个项目中已稳定运行 4 年之久,在 2 年前也把它开源出来,但没有做过推广。但是两年过去了,react-router 社区还是没有一套完整的解决方案,反而在 react-router v7 中自己演变成了一个和 remix 高度融合的一个框架项目,不由的想,这已经不是我想要的路由,于是,我想和和大家一起共建 react-router 生态型路由,适用当前不断变化的技术


GitHub地址

突破传统路由管理的局限

传统的 React 应用路由管理面临多重挑战:分散式的路由配置导致维护困难;权限与路由耦合度高;动态路由管理复杂;缺乏统一的路由守卫机制。这些问题在大型应用中尤为突出,严重影响了开发效率和代码质量,相信大家用了我这个库,开发效率一定能有很大的提升。详细的使用文档可参考 reac-router-manage使用文档或者 GitHub


react-router-manage 通过一种集中式声明式的配置方式,彻底颠覆了传统路由管理的思维模式,先来看如下示例codesandbox



import React from "react";import { MRouter, defineRouterConfig, useRouter } from "react-router-manage";import "./styles.css";
const Users = () => { const { currentRoute } = useRouter(); return <div>Users - {currentRoute.title}</div>;};const Profile = () => { const { currentRoute } = useRouter(); return <div>Profile - {currentRoute.title}</div>;};
const routerConfig = defineRouterConfig({ basename: "/", // 配置层级导航 routes: [ { path: "/", redirect: "/user", name: "根节点", items: [ { name: "user", // 每个路由对应一个全局唯一的name path: "user", // 路径会自动在内部转换为 /user, 由于这里没有配置component,进入 /user 会重定向到 /user/list title: "用户中心", // 路由名字 items: [ // items用于配置具有层级结构的导航,例如面包屑导航, { name: "userList", path: "list", // 路径会自动在内部转换为 /user/list component: Users, title: "用户列表", }, { name: "profile", path: "profile", // 路径会自动在内部转换为 /user/list component: Profile, title: "个人中心", }, ], }, ], }, ],});
function App() { return ( <MRouter routerConfig={routerConfig}> {(children) => <Layout>{children}</Layout>} </MRouter> );}
function Layout({ children }) { const { routesMap, navigate } = useRouter(); const navRoute = routesMap.user; return ( <div> <div className="nav"> 导航 <span> {navRoute.items.map((route) => { return ( <button onClick={() => navigate(route.path)} style={{ marginLeft: 20 }} > 去{route.title} </button> ); })} </span> </div> <div className="content">{children}</div> </div> );}
export default App;
复制代码

安装

npm install react-router-manage
复制代码

核心优势:超越简单的路由切换

1. 声明式配置与中央管理

告别以往零散和嵌套的路由定义方式,react-router-manage 采用集中声明式配置,通过单一数据源的方式实现路由的全局管理,大幅提升了路由系统的可维护性和可扩展性。

自动解析获取当前路由参数

使用 hook userRouter导出的对象方法, const { query, params } = useRouter(); 该 hook 封装了 react-roueteruseQuery, useParams hook,使用方式如下


codesandbox


import React from "react";import { useRouter } from "react-router-manage";
const User = () => { // 若url为 /user/profile?id=9527 const { query, params } = useRouter();
// 这里query.id为9527 return <div>该用户id为{query.id}</div>;};
export default UserList
复制代码


可以看到,点击“去用户信息”页能自动获取 query,获取params也差不多类似


2.便捷式的路由导航

路由跳转不再需要知道具体 pathname

内部会根据配置,自动把完整路径拼接好,并放到routesMap



下面是一个路由跳转示例


import React from "react";import { useRouter } from "react-router-manage";
cconst UserList = () => { const {routesMap, naviagete} = useRouter(); const onClick = () => { // 所有路由的配置都会放到routesMap对象里 navigate(routesMap.profile.pathname) } return <div><button>跳转我的个人中心</button></div>;};
export default UserList
复制代码

快捷拿到子级路由

例如我要渲染 /user 下的自己路由菜单,点击跳转到对应的路由。我们来看下面的导航如何做渲染



代码如下,我们只需要通过const navRoute = routesMap.user;即可拿到/user下的所有items,然后通过navRoute.items.map方法把导航菜单渲染出来


import React from "react";import { useRouter } from "react-router-manage";
function Layout({ children }) { const { routesMap, navigate } = useRouter(); const navRoute = routesMap.user; return ( <div> <div className="nav"> 导航 <span> {navRoute.items.map((route) => { return ( <button onClick={() => { let query = {}; // 如果点击的是用户信息页,则默认跳到 id为9527的用户 if (route.name === "userInfo") { query = { id: 9527 }; } navigate(route.path, { query }); }} style={{ marginLeft: 20 }} > 去{route.title} </button> ); })} </span> </div> <div className="content">{children}</div> </div> );}
复制代码

便携式参数传递

navigate 对象支持传路由参数 query, params,navigate: (to: string, {query: Record<string, any>; params: Record<string, any>; state: any}) => void},如下示例


import React from "react";import { useRouter } from "react-router-manage";
cconst UserList = () => { const {routesMap, naviagete} = useRouter(); const onClick = () => { // 所有路由的配置都会放到routesMap对象里 navigate(routesMap.profile.pathname, { query: {id: 9527} // 会自动拼成 /user/profile?id=9527 }) } return <div><button>跳转用户A的个人中心</button></div>;};
export default UserList
复制代码

3. 动态路由操作的优雅解决方案

在复杂应用的微前端架构或权限变化场景中,动态调整路由结构是一项常见需求。react-router-manage 提供了三个强大的 hooks, useAddRoutes,useUpdateRoutes, useRemoveRoutes。你可以很简单的动态操作路由


// 添加路由const addRoutes = useAddRoutes();// 动态更新路由配置const updateRoutes = useUpdateRoutes();// 移除路由const removeRoutes = useRemoveRoutes();
复制代码

添加路由 useAddRoutes

先来看效果,我们添加一个“路由管理页”



codesandbox


import React from 'react';import {useRouter, useAddRoutes} from 'react-router-manage';const UsersManage = () => {  const {currentRoute} = useRouter();  return <div>UsersManage - {currentRoute.title}</div>;}const AddRoutesComponent = ({ children }) => {  const addRoutes = useAddRoutes();  const onAdd = () => {      addRoutes([          {            parentName: "user", // 父路由名称 name            title: "员工管理页",            name: "userManage",            path: "manage",            component: UsersManage,          }    ]);  }
return <button onClick={onAdd}>添加一个路由</button>;};
复制代码


在上述代码中,点击 button 即可在 /user路径下,增加一个/user/manage的路由

更新路由 useUpdateRoutes

先来看效果,我们把“用户列表”页改为“工程师列表”页,先看效果



上面点击按钮后,导航和内容区域都自动修改了:用户列表->工程师列表,代码如下


codesandbox


import { useUpdateRoutes } from "react-router-manage";
const Page = () => { return <div>这是员工管理页</div>;};
const ModifyRoutes = () => { const updateRoutes = useUpdateRoutes();
const onClick = () => { updateRoutes([ { routeName: "userList", routeData: { title: "工程师列表", }, }, ]); };
return ( <div className="mb-16"> <button onClick={onClick}>把“用户列表”页改为“工程师列表”页</button> </div> );};
export default ModifyRoutes;
复制代码

删除路由 useRemoveRoutes

先来看效果,操作路径:1.添加“员工管理”页 2.跳转“员工管理”页 3.删除“员工管理”页 4.再去跳转到“员工管理”页



代码如下


import { useRemoveRoutes, useRouter } from "react-router-manage";
const Page = () => { return <div>这是员工管理页</div>;};
const ModifyRoutes = () => { const removeRoutes = useRemoveRoutes(); const { navigate } = useRouter();
const onClick = () => { removeRoutes(["staff"]); };
return ( <div className="mb-16"> <button onClick={onClick}>删除“员工管理”页</button> <button onClick={() => navigate("/user/staff")} style={{ marginLeft: 10 }} > 去“员工管理”页 </button> </div> );};
export default ModifyRoutes;
复制代码


看了上面的例子,有没有觉得路由的操作很简单

4. 多层次的权限控制体系

react-router-manage 突破了传统路由权限的局限性,提供了从全局到局部的多级权限控制机制:


  • 声明式权限配置:通过 code 属性简洁地定义路由访问权限

  • 权限继承模式:支持 parent 和 children 两种权限继承模式

  • 动态权限校验:结合 beforeEachMount 和 beforeEnter 实现精细的动态权限控制


中后台页面中经常不同的角色有不同的权限,一个非常普遍的做法是一个路由对应一个权限位,即权限 code,react-router-manage也做了封装,我们只需要配置路由的code


const routerConfig = defineRouterConfig({  basename: "/",  // 配置层级导航  routes: [    {      path: "/",      redirect: "/user",      name: "根节点",      items: [        {          name: "user", // 每个路由对应一个全局唯一的name          path: "user", // 路径会自动在内部转换为 /user, 由于这里没有配置component,进入 /user 会重定向到 /user/list          title: "用户中心", // 路由名字          items: [            // items用于配置具有层级结构的导航,例如面包屑导航,            {              name: "userList",              path: "list", // 路径会自动在内部转换为 /user/list              component: Users,              title: "用户列表",+             code: "USER_LIST",            },            {              name: "profile",              path: "profile", // 路径会自动在内部转换为 /user/list              component: Profile,              title: "个人中心",+             code: "PROFILE",            },            {              name: "userInfo",              path: "info",              component: User,              title: "用户信息",+             code: "USER_INFO",            },          ],        },      ],    },  ],});
复制代码


此时效果如下,我们配置的 3 个路由都没有权限。



接下来我们来添加当前登录的用户有的权限 code,假设该用户只有"用户列表的权限",则如下配置


function App() {  return (-    <MRouter routerConfig={routerConfig}>+    <MRouter routerConfig={routerConfig} permissionList={["USER_LIST"]}>      {(children) => <Layout>{children}</Layout>}    </MRouter>  );}
复制代码


我们再来看效果,发现用户列表页是可以访问的


同时,code 还支持传fn: (route: RouteTypeI) => boolean配置,例如


 {              name: "userList",              path: "list", // 路径会自动在内部转换为 /user/list              component: Users,              title: "用户列表",+             code: (route) => codes.inclues(route.name),}
复制代码



如果上述的方式还不适合你的需求,那你可以试试动态权限校验:结合全局beforeEachMount 和 beforeEnter 实现精细的动态权限控制,使用方式详见GitHub地址

5. 全面的路由守卫系统

借鉴了 Vue Router 的优秀设计,react-router-manage 引入了完整的路由守卫机制:


  • 全局前置守卫:beforeEachMount

  • 路由级前置守卫:beforeEnter

  • 组件级离开守卫:useBeforeLeave


这种分层的守卫架构使得开发者可以精确控制路由导航的每个环节,优雅处理权限验证、数据预加载和离开确认等复杂场景。

6.智能导航生成引擎

可自动生成符合企业规范的面包屑导航、菜单导航,可看示例代码例如 @rrmc/antd-breadcrumbs


npm i @rrmc/antd-breadcrumbs
复制代码


具体示例可看这里自动生成面包屑

从 React Router v5 到 v6 的平滑迁移

React Router v6 带来了诸多改进,但也带来了升级成本。react-router-manage 通过提供兼容层,大幅降低了迁移门槛:


  • 保留部分 v5 风格的 API

  • 透明处理 v6 的新特性

  • 引入 useHistory 等过渡性 hook

企业级应用的首选路由解决方案

React Router Manage 已在网易云商等多个企业级应用中经受了实战检验,证明了其在大型复杂应用中的可靠性和扩展性。它特别适合以下场景:


  • 大型管理后台:复杂权限系统、多层级导航

  • 微前端架构:动态路由管理、模块隔离

  • 多团队协作:标准化的路由配置、一致的导航体验

用户头像

shinpei

关注

还未添加个人签名 2018-11-14 加入

还未添加个人简介

评论

发布
暂无评论
面向企业级应用的React路由管理体系:react-router-manage实践_前端_shinpei_InfoQ写作社区