如何在反应中修复抽屉内的列表项

几天前,我在这里发布了一个问题:

如何在反应中使用单一方法扩展更多/更少的一个ListItem

我在这里得到了一个不完整的答案,我接受了(不知道我为什么这样做,看起来它一开始就起作用了)。我不得不承认我在这里的问题可能有点不清楚。

所以,长话短说,我想修复抽屉内的列表项以使其正常工作。我的意思是:

  • 当我点击可扩展项目时,它应该只扩展那个(点击的)项目。(这是有效的)

  • 当我点击另一个可扩展项目时,它应该展开那个项目,但关闭之前打开的。(不工作)

  • 当我单击可扩展项目内的项目时(在所有情况下都是查看或添加),它不应关闭该可扩展项目。(不工作,现在正在关闭所有项目)

这是我的助手可扩展项目组件的代码:


import { useState } from "react";


const ExpandableItem = props => {

  const [open, setOpen] = useState(false);

  console.log(props.menuItemName);

  return props.render({ open, setOpen });

};


export default ExpandableItem;

我在 material-ui 上搜索并发现了类似的东西,但我无法合并它。这是 material-ui 手风琴的链接:


https://material-ui.com/components/accordion/


如您所见,Customized accordions 的功能与我需要的非常相似。如果展开一个可折叠组,它会显示内容。如果您之后选择另一个,它会扩展并显示内容,并关闭前一个。


解决这个问题的最佳解决方案是什么?


饮歌长啸
浏览 74回答 1
1回答

森栏

问题是您没有存储当前展开的面板名称(或 ID)import { useState } from "react";const ExpandableItem = props => {&nbsp; &nbsp; const [itemState, setItemState] = useState({open: false, menuItemName: ""});&nbsp; &nbsp; console.log(props.menuItemName);&nbsp; &nbsp; 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}&nbsp; const ExpandableItemContainer = ({&nbsp; &nbsp; icon,&nbsp; &nbsp; menuItemName,&nbsp; &nbsp; firstItemName,&nbsp; &nbsp; firstItemLink,&nbsp; &nbsp; secondItemName,&nbsp; &nbsp; secondItemLink,&nbsp; }) => (&nbsp; &nbsp; <ExpandableItem&nbsp; &nbsp; &nbsp; render={(xprops) => (&nbsp; &nbsp; &nbsp; &nbsp; <>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItem button&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (menuItemName) => xprops.setItemState({open:!xprops.itemState.open, menuItemName}})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>{icon}</ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={menuItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {xprops.open ? <ExpandLess /> : <ExpandMore />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Collapse in={xprops.itemState.open} timeout="auto" unmountOnExit>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <List component="div" disablePadding>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItem&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={classes.nested}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; component={Link}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to={firstItemLink}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <VisibilityIcon />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={firstItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItem&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={classes.nested}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; component={Link}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to={secondItemLink}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <AddIcon />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={secondItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </List>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </Collapse>&nbsp; &nbsp; &nbsp; &nbsp; </>&nbsp; &nbsp; &nbsp; )}&nbsp; &nbsp; />&nbsp; );如果您想切换选择,您需要将状态保持在顶层(列表而不是 listItem 级别,如下所示export default function SideBar() {const classes = useStyles();const gymId = 1;const [itemState, setItemState] = React.useState({&nbsp; &nbsp; open: false,&nbsp; &nbsp; menuItemName: ""});const NonExpandableItemContainer = ({ icon, menuItemName, menuItemLink }) => (&nbsp; &nbsp; <ListItem button component={Link} to={menuItemLink}>&nbsp; &nbsp; <ListItemIcon>{icon}</ListItemIcon>&nbsp; &nbsp; <ListItemText primary={menuItemName} />&nbsp; &nbsp; </ListItem>);const ExpandableItemContainer = ({&nbsp; &nbsp; icon,&nbsp; &nbsp; menuItemName,&nbsp; &nbsp; firstItemName,&nbsp; &nbsp; firstItemLink,&nbsp; &nbsp; secondItemName,&nbsp; &nbsp; secondItemLink}) => (&nbsp; &nbsp; <ExpandableItem&nbsp; &nbsp; render={xprops => (&nbsp; &nbsp; &nbsp; &nbsp; <>&nbsp; &nbsp; &nbsp; &nbsp; <ListItem&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={() =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setItemState({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; open:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName === itemState.menuItemName&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? !itemState.open&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>{icon}</ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={menuItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {itemState.open ? <ExpandLess /> : <ExpandMore />}&nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; <Collapse&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in={itemState.open && menuItemName === itemState.menuItemName}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout="auto"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unmountOnExit&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <List component="div" disablePadding>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItem&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={classes.nested}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; component={Link}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to={firstItemLink}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <VisibilityIcon />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={firstItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItem&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={classes.nested}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; component={Link}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to={secondItemLink}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <AddIcon />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItemIcon>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ListItemText primary={secondItemName} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ListItem>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </List>&nbsp; &nbsp; &nbsp; &nbsp; </Collapse>&nbsp; &nbsp; &nbsp; &nbsp; </>&nbsp; &nbsp; )}&nbsp; &nbsp; />);return (&nbsp; &nbsp; <Drawer&nbsp; &nbsp; className={classes.drawer}&nbsp; &nbsp; variant="permanent"&nbsp; &nbsp; classes={{&nbsp; &nbsp; &nbsp; &nbsp; paper: classes.drawerPaper&nbsp; &nbsp; }}&nbsp; &nbsp; >&nbsp; &nbsp; <Toolbar />&nbsp; &nbsp; <div className={classes.drawerContainer}>&nbsp; &nbsp; &nbsp; &nbsp; <List&nbsp; &nbsp; &nbsp; &nbsp; component="nav"&nbsp; &nbsp; &nbsp; &nbsp; aria-labelledby="nested-list-subheader"&nbsp; &nbsp; &nbsp; &nbsp; className={classes.root}&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; <NonExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<HomeIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Home"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemLink={"/gym/" + gymId + "/home"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<SupervisorAccountIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Administrators"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewAccount"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addAccount"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<AccessibilityNewIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Trainers"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewAccount"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addAccount"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<FaceIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Members"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewAccount"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addAccount"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<FitnessCenterIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Trainings"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewTrainings"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addTraining"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <NonExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<EventIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Training schedules"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemLink={"/gym/" + gymId + "/viewTrainingSchedules"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<PanoramaWideAngleIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Halls"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewHalls"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addHall"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <ExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<ReceiptIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Pricelist"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemName="View"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstItemLink={"/gym/" + gymId + "/viewPricelist"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemName="Add"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secondItemLink={"/gym/" + gymId + "/addPricelistItem"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <NonExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<PhoneIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Contact"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemLink={"/gym/" + gymId + "/contact"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; <NonExpandableItemContainer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; icon={<SettingsIcon />}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemName="Settings"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menuItemLink={"/gym/" + gymId + "/settings"}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; </List>&nbsp; &nbsp; </div>&nbsp; &nbsp; </Drawer>);}codesandbox链接:https ://otzsl.csb.app/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript