React微前端(模块联邦)中useRoutes匹配正确pathname却返回null
我在模块联邦嵌入主应用的微前端项目里写了这段React代码(使用react-router-dom v6.10.0):
// inside my microfrontend. const path = '/another-component-path'; function Component () { const location = useLocation(); console.log(location.pathname === path); // 输出true const routes = useRoutes([ { path: path, element: <AnotherComponent /> } ]); console.log(routes); // 输出null——这怎么可能? return routes; } export default Component;
浏览器提示No routes matched location '/another-component-path',明明location.pathname和路由路径完全匹配,但useRoutes返回null,用<Routes>/<Route>组件也遇到同样问题,请问问题出在哪里?
问题原因及解决办法
这问题大概率是模块联邦微前端场景下的路由上下文冲突或者路由路径配置逻辑错误,从这几个方向排查:
- 检查主应用与微前端的路由basename配置
如果主应用把微前端挂载在某个子路径下(比如/my-micro-app/*),微前端内部的路由必须设置对应的basename,否则useRoutes会基于主应用的根路径去匹配。比如在微前端的路由上下文里添加:
<BrowserRouter basename="/my-micro-app"> {/* 你的组件 */} </BrowserRouter>
或者如果是继承主应用的路由上下文,微前端内部的路由路径应该用相对路径(去掉开头的斜杠),比如把path改成'another-component-path',而不是'/another-component-path'。
确认react-router-dom版本一致性
主应用和微前端必须使用完全相同版本的react-router-dom,模块联邦下不同版本的路由库会导致上下文不兼容,useRoutes无法正确读取路由状态,哪怕路径匹配也会返回null。排查路由上下文的传递
微前端的组件必须在正确的路由上下文内渲染,如果主应用已经提供了Router上下文,微前端不要重复嵌套Router;反之如果微前端需要独立路由,必须自己包裹Router组件,确保useLocation和useRoutes属于同一个上下文。检查路径匹配的严格性
React Router v6中,useRoutes的路径匹配默认是精确匹配,如果你的location.pathname后面有多余的斜杠(比如/another-component-path/),而你的path是/another-component-path,就会匹配失败。可以在路由配置里添加end: false允许后缀匹配:
{ path: path, element: <AnotherComponent />, end: false }
内容的提问来源于stack exchange,提问作者Сергей Кочкин

