1 回答
TA贡献1810条经验 获得超5个赞
问题是您没有存储当前展开的面板名称(或 ID)
import { useState } from "react";
const ExpandableItem = props => {
const [itemState, setItemState] = useState({open: false, menuItemName: ""});
console.log(props.menuItemName);
return props.render({ itemState, setItemState });
};
export default ExpandableItem;
我已将变量 [open, setOpen] 重命名为 [itemState, setItemState],因此需要在其使用的任何地方进行更改,(或者您可以添加单独的变量来设置当前选定的 menuName)
在您的 ExpandableItemContainer 中,在 onClick 处理程序中传递适当的值 xprops.setItemState({open:!xprops.itemState.open, menuItemName}})
同样在 Collapse 组件中将 in Prop 更改为
in={xprops.itemState.open && menuItemName === xprops.itemState.menuItemName}
const ExpandableItemContainer = ({
icon,
menuItemName,
firstItemName,
firstItemLink,
secondItemName,
secondItemLink,
}) => (
<ExpandableItem
render={(xprops) => (
<>
<ListItem button
onClick={
(menuItemName) => xprops.setItemState({open:!xprops.itemState.open, menuItemName}})
}
>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={menuItemName} />
{xprops.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={xprops.itemState.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem
button
className={classes.nested}
component={Link}
to={firstItemLink}
>
<ListItemIcon>
<VisibilityIcon />
</ListItemIcon>
<ListItemText primary={firstItemName} />
</ListItem>
<ListItem
button
className={classes.nested}
component={Link}
to={secondItemLink}
>
<ListItemIcon>
<AddIcon />
</ListItemIcon>
<ListItemText primary={secondItemName} />
</ListItem>
</List>
</Collapse>
</>
)}
/>
);
如果您想切换选择,您需要将状态保持在顶层(列表而不是 listItem 级别,如下所示
export default function SideBar() {
const classes = useStyles();
const gymId = 1;
const [itemState, setItemState] = React.useState({
open: false,
menuItemName: ""
});
const NonExpandableItemContainer = ({ icon, menuItemName, menuItemLink }) => (
<ListItem button component={Link} to={menuItemLink}>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={menuItemName} />
</ListItem>
);
const ExpandableItemContainer = ({
icon,
menuItemName,
firstItemName,
firstItemLink,
secondItemName,
secondItemLink
}) => (
<ExpandableItem
render={xprops => (
<>
<ListItem
button
onClick={() =>
setItemState({
open:
menuItemName === itemState.menuItemName
? !itemState.open
: true,
menuItemName
})
}
>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={menuItemName} />
{itemState.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
in={itemState.open && menuItemName === itemState.menuItemName}
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
<ListItem
button
className={classes.nested}
component={Link}
to={firstItemLink}
>
<ListItemIcon>
<VisibilityIcon />
</ListItemIcon>
<ListItemText primary={firstItemName} />
</ListItem>
<ListItem
button
className={classes.nested}
component={Link}
to={secondItemLink}
>
<ListItemIcon>
<AddIcon />
</ListItemIcon>
<ListItemText primary={secondItemName} />
</ListItem>
</List>
</Collapse>
</>
)}
/>
);
return (
<Drawer
className={classes.drawer}
variant="permanent"
classes={{
paper: classes.drawerPaper
}}
>
<Toolbar />
<div className={classes.drawerContainer}>
<List
component="nav"
aria-labelledby="nested-list-subheader"
className={classes.root}
>
<NonExpandableItemContainer
icon={<HomeIcon />}
menuItemName="Home"
menuItemLink={"/gym/" + gymId + "/home"}
/>
<ExpandableItemContainer
icon={<SupervisorAccountIcon />}
menuItemName="Administrators"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewAccount"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addAccount"}
/>
<ExpandableItemContainer
icon={<AccessibilityNewIcon />}
menuItemName="Trainers"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewAccount"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addAccount"}
/>
<ExpandableItemContainer
icon={<FaceIcon />}
menuItemName="Members"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewAccount"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addAccount"}
/>
<ExpandableItemContainer
icon={<FitnessCenterIcon />}
menuItemName="Trainings"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewTrainings"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addTraining"}
/>
<NonExpandableItemContainer
icon={<EventIcon />}
menuItemName="Training schedules"
menuItemLink={"/gym/" + gymId + "/viewTrainingSchedules"}
/>
<ExpandableItemContainer
icon={<PanoramaWideAngleIcon />}
menuItemName="Halls"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewHalls"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addHall"}
/>
<ExpandableItemContainer
icon={<ReceiptIcon />}
menuItemName="Pricelist"
firstItemName="View"
firstItemLink={"/gym/" + gymId + "/viewPricelist"}
secondItemName="Add"
secondItemLink={"/gym/" + gymId + "/addPricelistItem"}
/>
<NonExpandableItemContainer
icon={<PhoneIcon />}
menuItemName="Contact"
menuItemLink={"/gym/" + gymId + "/contact"}
/>
<NonExpandableItemContainer
icon={<SettingsIcon />}
menuItemName="Settings"
menuItemLink={"/gym/" + gymId + "/settings"}
/>
</List>
</div>
</Drawer>
);
}
codesandbox链接:https ://otzsl.csb.app/
添加回答
举报