React项目中如何为侧边栏路由动态注入URL中的项目ID
解决方法
这里提供两种常用的实现方案,你可以根据自己的项目习惯选择:
方案1:侧边栏内部动态替换路径(改动最小)
这种方案不需要修改现有配置结构,只需要调整侧边栏的逻辑即可:
- 修正Sidebar组件的参数取值
你当前Sidebar里取的是key参数,但路由里定义的参数是id,先修改这行:
// 原代码 const { key } = useParams(); // 修改为 const { id } = useParams();
- 传递id到SidebarItem组件
在Sidebar组件渲染SidebarItem时,把拿到的id作为prop传入:
<SidebarItem depthStep={depthStep} depth={depth} expanded={expanded} item={sidebarItem} projectId={id} // 新增这行 />
别忘了子菜单循环里的SidebarItem也要加同样的prop。
3. 在SidebarItem中替换路径占位符
两个地方需要修改:
- 跳转路径替换
- 激活状态判断的路径替换
function SidebarItem({ depthStep = 10, depth = 0, expanded, item, projectId, ...rest }) { // ...其他原有逻辑 function onClick(e) { if (Array.isArray(items)) { toggleCollapse(); } if (onClickProp) { onClickProp(e, item); // 替换路径里的:id占位符 const realPath = item.path.replace(':id', projectId); history.push(realPath); } } // ...其他原有逻辑 return ( <> <ListItem className={classes.sidebarItem} onClick={onClick} button dense // 激活判断也用替换后的真实路径 className={location.pathname === item.path.replace(':id', projectId) ? classes.active : null} {...rest} > {/* 其他原有渲染逻辑 */} </> ) }
方案2:侧边栏配置改为动态工厂函数(可维护性更高)
如果后续需要加更多动态参数,推荐用这种方案,把静态配置改成接收参数返回配置的函数:
- 修改侧边栏配置文件
把原来导出的数组改成导出一个接收id参数的函数:
function onClick(e, item) {} // 从导出数组改为导出工厂函数 const getItemsProject = (id) => [ { name: 'companies', label: translate('sidebarProjectCompanies'), Icon: CompanyIcon, path: `/project/${id}/companies`, // 直接填充id onClick, }, { name: 'currencies', label: translate('sidebarProjectCurrencies'), Icon: CurrencyIcon, path: `/project/${id}/currencies`, // 直接填充id onClick, } ]; export default getItemsProject;
- 在ProjectLayout中生成动态配置
在页面模板中先拿到id,调用工厂函数生成实际的导航配置,再传给侧边栏:
import React from 'react'; import { useParams } from 'react-router-dom'; // 新增导入 import { Grid, makeStyles } from '@material-ui/core'; import { AppContent, AppHeader, SidebarApp, } from '../components/index'; import getItemsProject from '../components/itemsSidebar/itemsProject'; // 导入工厂函数 const useStyles = makeStyles(theme => ({ appContent: { paddingLeft: 240, width: '100%', backgroundColor: theme.palette.background.paper, }, })); const ProjectLayout = () => { const classes = useStyles(); const { id } = useParams(); // 从url取项目id const projectSidebarItems = getItemsProject(id); // 生成动态导航配置 return ( <div className={classes.appContent}> <AppHeader /> <Grid container direction="row"> <SidebarApp items={projectSidebarItems} /> {/* 传入动态配置 */} <AppContent /> </Grid> </div> ); }; export default ProjectLayout;
这种方案不需要修改侧边栏的原有逻辑,所有路径在传入前就已经填充完成,后续修改配置更方便。
补充说明
如果你需要在非/project/:id/*的路由下也能拿到当前选中的项目id,可以把id存在Redux store里,在列表选中项目的时候就写入store,后续使用直接从store取值即可。
内容的提问来源于stack exchange,提问作者Cleiton Freitas
相关产品推荐
相关产品推荐

