React Route动态路径场景下如何将无效路径重定向到根路径/
问题根因
你遇到的问题本质是初始渲染时序问题:
- 路由组件首次渲染时,Redux中的
details数据还未完成拉取,此时条件判断details && details.show_page返回false,动态的path2路由不会被渲染到Switch内部 - Switch在首次匹配时找不到对应路径的Route,直接命中最后的全局Redirect,路由跳转到根路径
- 等后续
details数据加载完成,动态Route已经错过匹配时机,跳转已经生效
解决方案
下面提供两种可直接落地的解决方式,根据你的业务场景选择即可:
方式1:加数据加载等待逻辑,等details加载完成后再渲染路由匹配逻辑
假设你可以从Redux中取到details的加载状态isDetailsLoading,修改代码如下:
<Router> {/* 数据加载完成前渲染加载态,不执行路由匹配 */} {isDetailsLoading ? <LoadingSpinner /> : ( <Switch> <Route exact path="/path1/" component={Page1} /> {details?.show_page && ( <Route path={`/${details.page_url.replace(/^\/+/, '')}`} // 处理page_url自带前缀斜杠的情况 component={Page2} /> )} <Redirect from="*" to="/" /> </Switch> )} </Router>
方式2:不做Route的条件渲染,将权限判断移到Route内部
始终保留动态路由的注册,匹配到路径后再判断是否有权限渲染Page2:
<Router> <Switch> <Route exact path="/path1/" component={Page1} /> <Route path="/:pageUrl" render={(routeProps) => { // 匹配到动态路径后再校验数据和权限 if (details?.show_page && routeProps.match.params.pageUrl === details?.page_url) { return <Page2 {...routeProps} /> } // 校验不通过则跳转到根路径 return <Redirect to="/" /> }} /> <Redirect from="*" to="/" /> </Switch> </Router>
额外注意点
- 你当前注册的
/path1/路由带尾斜杠,开启exact的情况下,用户输入/path1(不带尾斜杠)会匹配失败,可添加strict={false}属性关闭严格斜杠匹配 - 拼接动态路径时要注意避免出现双斜杠的问题,比如
details.page_url如果本身开头带/,拼接后会得到//xxx,导致匹配失败,建议拼接前先去除开头的斜杠
内容的提问来源于stack exchange,提问作者Miss. Tea
相关产品推荐
相关产品推荐

