应利用 usematches() 动态获取当前路由匹配结果,以 matches 最深层的 id 或 data 为 key 查找预定义菜单策略,实现按组件类型分发右键菜单,避免硬编码和路径字符串匹配。

在自研低代码大屏系统中,画布区右键菜单需按组件类型动态展示不同选项(如图表组件支持“编辑配置”“复制”,容器组件支持“添加子项”“设置背景”),而不能全局统一。利用 matches(来自 react-router@6.4+ 的路由匹配结果)实现菜单分发,本质是把「当前右键击中的组件所属的路由上下文」作为菜单策略的依据,而非硬编码或手动维护映射表。
用 matches 获取当前激活的路由层级与参数
matches 是 useMatches() 返回的数组,按嵌套深度从外到内排列,每个元素含 id、pathname、params、data 等字段。关键点在于:你应在画布组件内部调用 useMatches(),并在右键事件触发时读取最新匹配结果。
- 确保画布区域(如
CanvasArea)本身被包裹在<outlet></outlet>或对应路由路径下,使matches能反映真实导航状态 - 若组件支持嵌套路由(如 `/dashboard/123/chart/456`),则
matches[matches.length - 1]通常是叶子路由,其params可能含componentId或type - 避免在事件回调闭包中捕获过期的
matches,应每次右键时实时调用useMatches()或通过useRef同步最新值
将 matches 映射为菜单策略 ID
不直接在菜单渲染逻辑里写一堆 if (match.id === 'chart-route') {...},而是提取可复用的策略标识,例如:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 取最深一级
match.id作为策略 key(如'chart-edit'、'container-layout') - 或组合
match.data.componentType+match.data.editable构建策略名(需提前在路由loader或element中注入) - 定义策略注册表:
const menuStrategies = { 'chart-edit': chartMenuItems, 'container-layout': containerMenuItems }
在右键事件中动态生成菜单项
画布区监听 onContextMenu,阻止默认行为后,基于当前 matches 查策略并渲染:
- 用
useState存菜单坐标和可见性,用useCallback封装菜单生成逻辑,避免重复计算 - 示例逻辑:const match = useMatches().at(-1); const strategy = menuStrategies[match?.id] || defaultMenuItems;
- 若右键目标是具体组件实例(如通过
event.target.dataset.componentId获取),可进一步结合match.params和组件元数据做细粒度控制(如禁用“删除”对只读组件)
注意嵌套组件与路由边界问题
低代码画布常存在多层嵌套容器(如 Group → Panel → Chart),但路由通常只声明到逻辑区块级。此时需约定:
- 所有可右键的组件必须挂载在明确的路由节点下(避免浮动组件脱离路由树)
- 若需按实际 DOM 组件类型分发菜单,可在右键时从
event.target向上查找带data-component-type的父节点,再与matches中的componentType对齐,作为 fallback - 不依赖
location.pathname做字符串匹配——它无法区分同一路由下的不同实例,而matches天然携带params和data










