React基于URL的路由条件渲染是否合理,有无更优方案?
React路由实现方案优化建议
现有方案的问题
你当前的写法虽然可以正常运行,但不属于React路由的推荐实践,存在几个明显的缺陷:
- 手动硬编码判断路径非常冗余,需要额外兼容带末尾斜杠和不带斜杠的情况,后续新增
/:id参数后,路径会变成类似/spaces/123/members的格式,不可能穷举所有id值做硬编码判断,现有逻辑必然失效 - 可维护性极差,每新增一个路径都要加一段if分支,路由规则多了之后代码会非常混乱
- 容易出现低级错误,比如你现有代码中
/profile根路径下赋值的是typeContent,但实际渲染的是Content,会导致该路径下内容为空
优化方案(和你当前使用的React Router v5写法完全兼容)
第一步:简化App.js的路由配置
不需要在父路由里定义所有子路径数组,直接保留父路由规则即可:
// App.js 修改后 <Route path="/spaces" component={Spaces} /> <Route path="/profile" component={Spaces} />
第二步:用嵌套路由代替手动条件判断
React Router本身就支持嵌套路由,自带路径匹配能力,自动处理末尾斜杠兼容,原生支持动态参数:
// Spaces.js 修改后 import { Route, useRouteMatch } from 'react-router-dom'; function Spaces() { // 自动获取当前父路由的匹配信息,不用硬编码路径 const { path } = useRouteMatch(); // 直接用路由提供的匹配方法判断路由类型,不用手动判断路径 const isAdminRoute = useRouteMatch(`${path}/admin`); const isProfileRoute = useRouteMatch('/profile'); return ( <div> <div className='page-content' style={{ maxWidth: !isAdminRoute ? '980px': '800px'}}> <div className='profile-page tx-13'> {(!isProfileRoute || isAdminRoute) ? <Cover admin={isAdminRoute} profile={isProfileRoute}/> : <CoverProfile admin={isAdminRoute} profile={isProfileRoute}/> } {/* 嵌套路由自动匹配,支持可选id参数,末尾加?表示参数可选 */} <Route exact path={[path, `${path}/:id`]} component={isProfileRoute ? ProfileContent : SpaceContent} /> <Route path={`${path}/members/:id?`} component={SpaceMembers} /> <Route path={`${path}/about/:id?`} component={SpaceAbout} /> <Route path={`${path}/admin/:id?`} component={SpaceAdmin} /> <Route path={`${path}/comments/:id?`} component={ProfileSpace} /> <Route path={`${path}/spaces/:id?`} component={ProfileSpace} /> <Route path={`${path}/cloud/:id?`} component={ProfileSpace} /> </div> </div> </div> ); } export default Spaces;
优化后的优势
- 完全不用手动写路径判断逻辑,路由库自动处理匹配,天然兼容带/不带末尾斜杠的场景
- 新增
/:id参数完全不需要修改匹配逻辑,只需要通过match.params.id就能拿到参数值 - 后续新增路由只需要加一行
配置即可,代码清晰易维护 - 没有硬编码的路径字符串,父路由路径修改后子路由自动同步,不会出现路径不匹配的问题
内容的提问来源于stack exchange,提问作者AlyaKra
相关产品推荐
相关产品推荐

