React Router v5类组件路由问题:调整路由顺序致计算器路由失效
解决React Router v5中带参数路由覆盖具体路由的问题
问题原因
在React Router v5的Switch组件中,路由是按定义顺序从上到下匹配的,一旦匹配到第一个符合条件的路由就会停止后续匹配。当你把/calculator/:amcName这类带动态参数的路由放在/calculator/sip-calculator等具体路由前面时,访问/calculator/sip-calculator会被/calculator/:amcName优先匹配——因为:amcName会匹配任意字符串(这里就是sip-calculator),导致后面的具体路由永远不会被命中。
解决方案
方案1:调整路由顺序(推荐)
将具体的、无动态参数的路由放在带动态参数的路由前面,确保具体路径先被匹配:
修改Routers数组的顺序,把带参数的路由移到所有/calculator/xxx具体路由的后面:
const Routers = [ { path: '/', component: "./views/home", exact: true }, { path: '/login', component: "./views/login", fullLayout: true, hideFooter: true }, { path: '/register', component: "./views/login", fullLayout: true, hideFooter: true }, { path: '/mutual-fund/deskpay', component: "./views/deskpay", fullLayout: true, hideFooter: true }, // 所有具体计算器路由放在前面 { path: '/calculator/sip-calculator', component: "./views/calculator/sip_calculator.js" }, { path: '/calculator/lumpsum-calculator', component: "./views/calculator/lumpsum_calculator.js" }, { path: '/calculator/sip-reverse-calculator', component: "./views/calculator/sip_reverse_calculator.js" }, { path: '/calculator/cagr-calculator', component: "./views/calculator/cagr-calculator.js" }, { path: '/calculator/xirr-mutual-fund-calculator', component: "./views/calculator/xirr-calculator" }, { path: '/calculator/exit-load-calculator', component: "./views/calculator/exit-load-calculator" }, { path: '/calculator/reverse-lumpsum-calculator', component: "./views/calculator/lumpsum-reverse-calculator" }, { path: '/calculator/stepup-sip-calculator', component: "./views/calculator/sip-stepup-calculator" }, { path: '/calculator/sip-calculator-with-inflation', component: "./views/calculator/sip-calculator-with-inflanation.js" }, { path: '/calculator/capital-gain-calculator', component: "./views/calculator/capital-gain-calculator" }, { path: '/calculator', component: "./views/calculator/index.js" }, // 带参数的路由放在具体路由之后 { path: '/calculator/:amcName', component: "./views/amc-calculator" }, { path: '/500', component: "./views/error/500" }, { path: '*', component: "./views/error/404" }, ]
方案2:给参数路由添加exact属性(可选)
如果你需要保持参数路由的顺序,可以给/calculator/:amcName添加exact: true,让它只匹配完全符合/calculator/xxx的路径(不会匹配/calculator/xxx/yyy这类多级路径):
{ path: '/calculator/:amcName', component: "./views/amc-calculator", exact: true },
这样即使它放在具体路由前面,访问/calculator/sip-calculator时,因为路径长度和/calculator/:amcName不完全一致,不会被匹配,后续的具体路由就能正常命中。
额外优化点
- 添加唯一
key属性:当前Routers数组的项没有key,map时建议用path作为唯一key,避免React警告:
{Routers.map(({ path, component: C, fullLayout, hideFooter, exact }) => { const Component = lazy(() => import(`${C}`)) return ( <Route key={path} // 用path作为唯一key path={path} exact={exact} render={(props) => { return ( <React.Fragment> {!fullLayout && <Header />} <Component {...props}/> {!hideFooter && <Footer/>} </React.Fragment> ); }} /> ) })}
- 用
Suspense包裹懒加载组件:lazy加载的组件需要配合Suspense使用,否则组件加载时会报错,建议在AppRouter中添加:
import React, { lazy, Suspense } from "react"; // ... render() { return ( <Router history={history}> <Suspense fallback={<div>Loading...</div>}> <Switch> {/* 路由项 */} </Switch> </Suspense> </Router> ); }
内容的提问来源于stack exchange,提问作者manimk
相关产品推荐
相关产品推荐

