为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

饮歌长啸 2022-12-02 15:58:30
几天前,我在这里发布了一个问题:如何在反应中使用单一方法扩展更多/更少的一个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 的功能与我需要的非常相似。如果展开一个可折叠组,它会显示内容。如果您之后选择另一个,它会扩展并显示内容,并关闭前一个。解决这个问题的最佳解决方案是什么?
查看完整描述

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/


查看完整回答
反对 回复 2022-12-02
  • 1 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信