react-router-dom多Switch架构下统一NotFound路由配置问题咨询
问题根因
你当前的路由结构存在两个核心逻辑问题,直接导致了内容叠加渲染:
- 外层Switch仅包含一个无路径限制的Route,所有访问请求都会命中该Route,导致内部的
<PublicRoutes />和用户身份对应的<PrivateRoutes />/<AuthRoutes />是并列渲染关系,而非路由互斥匹配关系 - 每个子路由模块的Switch内部都配置了无路径的NotFound路由,只要当前子Switch没有匹配到对应路径,就会渲染NotFound,自然会和前面已经匹配到的Public路由内容叠加显示
改造方案
可以实现全局统一的NotFound组件,只需要调整路由结构,移除子模块内部的NotFound路由,将统一NotFound放在外层Switch的最末尾即可,改造步骤如下:
步骤1:改造根Router.tsx
调整外层Switch的匹配逻辑,让三个路由模块按顺序互斥匹配,最后放置全局NotFound路由:
export default function Routes(): JSX.Element { const [user] = useUser(); return ( <Switch> {/* 优先匹配公共路由模块 */} <Route path="/"> <PublicRoutes /> </Route> {/* 公共路由未匹配时,匹配对应身份的路由模块 */} <Route path="/"> {user.user ? <PrivateRoutes /> : <AuthRoutes />} </Route> {/* 所有模块均未匹配时,统一渲染全局NotFound */} <Route component={() => ( <ErrorPage errorCode={user.user ? ERROR_404_ROUTE.errorCode : ERROR_403_ROUTE.errorCode} errorMessage={user.user ? ERROR_404_ROUTE.errorMessage : ERROR_403_ROUTE.errorMessage} /> )} /> </Switch> ); }
步骤2:改造所有子路由模块
移除PublicRoutes、PrivateRoutes、AuthRoutes内部的NotFound路由即可,以AuthRoutes为例:
export default function AuthRoutes(): JSX.Element { return ( <Switch> {/* 登录相关页面 */} <Route exact path="/"> <Redirect to="/login" /> </Route> <Route exact path="/login" component={Login} /> <Route exact path="/oauth-callback" component={Authentication} /> {/* 移除原有的NotFound路由,子模块未匹配时返回null,外层Switch会继续向下匹配 */} </Switch> ); }
匹配逻辑说明
外层Switch会按从上到下的顺序执行匹配:
- 先进入PublicRoutes的Switch匹配,命中对应路由则渲染公共页面,未命中则返回null,外层Switch继续向下匹配
- 进入身份对应的路由模块Switch匹配,命中则渲染对应业务页面,未命中则返回null,外层Switch继续向下匹配
- 前两个模块均未命中时,直接命中末尾的全局NotFound路由,统一渲染错误页
如果需要区分未登录/登录状态的错误提示,直接在全局NotFound组件中读取用户状态判断即可。
内容的提问来源于stack exchange,提问作者DrunkOldDog
相关产品推荐
相关产品推荐

