【问题标题】:React/Material UI Drawer With Nested List Items Closes on Click具有嵌套列表项的 React/Material UI 抽屉在单击时关闭
【发布时间】:2021-02-23 00:12:29
【问题描述】:

我在我的 React 项目中使用 Material-UI,当我添加嵌套列表项时,我遇到了让抽屉正常工作的问题。在我添加它们之前,一切都很好。我相信根本原因是通过单击下拉菜单并将列表项的状态更改为打开状态,我导致应用程序重新呈现。不知道如何解决。

问题:当您单击顶层时,嵌套列表项会自动关闭抽屉。然后用户必须再次打开抽屉才能看到下拉列表中的项目。

所需功能:用户单击菜单项以打开抽屉。用户可以单击“Leadership Triad”并在抽屉保持打开状态时查看其中的菜单项。当用户点击关闭时,抽屉关闭。

代码沙盒 https://codesandbox.io/s/material-ui-nested-menu-forked-qqdiv

我的代码

import React, { useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";
import Drawer from "@material-ui/core/Drawer";
import List from "@material-ui/core/List";
import Divider from "@material-ui/core/Divider";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import HomeIcon from "@material-ui/icons/Home";
import AccountCircle from "@material-ui/icons/AccountCircle";
import ExitToAppIcon from "@material-ui/icons/ExitToApp";
import ExpandLess from "@material-ui/icons/ExpandLess";
import ExpandMore from "@material-ui/icons/ExpandMore";
import PeopleIcon from "@material-ui/icons/People";
import BusinessIcon from "@material-ui/icons/Business";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import { Link as RouterLink } from "react-router-dom";
import Collapse from "@material-ui/core/Collapse";

const useStyles = makeStyles(theme => ({
    root: { flexGrow: 1 },
    menuButton: { marginRight: theme.spacing(2) },
    title: { flexGrow: 1 },
    list: { width: 250 },
    nested: { paddingLeft: theme.spacing(4) },
}));

const Header = () => {
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [anchorEl, setAnchorEl] = useState(null);

    const [leadershipTriadMenuOpen, setLeadershipTriadMenuOpen] = useState(false);

    const handleLeadershipTriadClick = () => {
        setLeadershipTriadMenuOpen(!leadershipTriadMenuOpen);
    };

    const handleClick = event => {
        setAnchorEl(event.currentTarget);
    };

    const handleClose = () => {
        setAnchorEl(null);
    };

    const toggleDrawer = () => {
        setDrawerOpen(!drawerOpen);
    };
    const classes = useStyles();
    return (
        <div className={classes.root}>
            <AppBar position="static">
                <Toolbar>
                    <IconButton
                        edge="start"
                        className={classes.menuButton}
                        color="inherit"
                        aria-label="menu"
                        onClick={() => toggleDrawer()}
                    >
                        <MenuIcon />
                        <Drawer
                            anchor="left"
                            open={drawerOpen}
                            onClose={() => toggleDrawer()}
                        >
                            <div className={classes.list}>
                                <List>
                                    <ListItem button component={RouterLink} to="/">
                                        <ListItemIcon>
                                            <HomeIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Home" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        onClick={() => handleLeadershipTriadClick()}
                                    >
                                        <ListItemIcon>
                                            <HomeIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Leadership Triad" />
                                        {leadershipTriadMenuOpen ? (
                                            <ExpandLess />
                                        ) : (
                                            <ExpandMore />
                                        )}
                                    </ListItem>
                                    <Collapse
                                        in={leadershipTriadMenuOpen}
                                        timeout="auto"
                                        unmountOnExit
                                    >
                                        <List component="div" disablePadding>
                                            <ListItem button className={classes.nested}>
                                                <ListItemIcon>
                                                    <HomeIcon />
                                                </ListItemIcon>
                                            </ListItem>
                                        </List>
                                    </Collapse>
                                    <ListItem button>
                                        <ListItemIcon>
                                            <InboxIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Testing" />
                                    </ListItem>
                                    <ListItem button>
                                        <ListItemIcon>
                                            <InboxIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Testing" />
                                    </ListItem>
                                </List>
                                <Divider />
                                <List>
                                    <ListItem
                                        button
                                        component={RouterLink}
                                        to="/admin/companies"
                                    >
                                        <ListItemIcon>
                                            <BusinessIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Companies" />
                                    </ListItem>
                                    <ListItem
                                        button
                                        component={RouterLink}
                                        to="/admin/users"
                                    >
                                        <ListItemIcon>
                                            <PeopleIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Users" />
                                    </ListItem>
                                </List>
                                <Divider />
                                <List>
                                    <ListItem button component={RouterLink} to="/profile">
                                        <ListItemIcon>
                                            <AccountCircle color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Profile" />
                                    </ListItem>
                                    <ListItem button component={RouterLink} to="/logout">
                                        <ListItemIcon>
                                            <ExitToAppIcon color="primary" />
                                        </ListItemIcon>
                                        <ListItemText primary="Logout" />
                                    </ListItem>
                                </List>
                            </div>
                        </Drawer>
                    </IconButton>
                    <Typography variant="h6" className={classes.title}>
                        Leadership Program
                    </Typography>
                    <IconButton color="inherit" onClick={handleClick}>
                        <AccountCircle />
                    </IconButton>
                    <Menu
                        id="admin-menu"
                        anchorEl={anchorEl}
                        keepMounted
                        open={Boolean(anchorEl)}
                        onClose={handleClose}
                    >
                        <MenuItem
                            component={RouterLink}
                            to="/profile"
                            onClick={handleClose}
                        >
                            Profile
                        </MenuItem>
                        <MenuItem
                            onClick={handleClose}
                            component={RouterLink}
                            to="/logout"
                        >
                            Logout
                        </MenuItem>
                    </Menu>
                </Toolbar>
            </AppBar>
        </div>
    );
};

export default Header;

【问题讨论】:

  • 问题是抽屉的&lt;IconButton&gt;(父级)有 onClick 监听器,所以尝试将 onClick 监听器提供给个人 ListItem 而不要将其提供给 ListItemIcon
  • 您是否尝试过这样做^^^^(上述解决方案)
  • @GayatriDipali 非常感谢您,先生!这真的很好。我只是将 onClick 移动到 MenuIcon 本身而不是按钮,因为按钮是父级。
  • @GayatriDipali 我确实收到一个错误,说我需要在父元素上设置 onClick。我所做的是将 onClick 侦听器保留在我拥有的位置,但将 Drawer 代码移到 IconButton 之外,因此它不再是父级。问题解决了。
  • 我移出了整个抽屉,所以它不再是按钮的子元素,而是兄弟元素。

标签: javascript node.js reactjs material-ui


【解决方案1】:

您是否尝试过用 ListItemSecondaryAction 包围 IconButton?

<ListItemSecondaryAction>
  <IconButton onClick={handleOnClick}>
    {openState ? <ExpandLess /> : <ExpandMore />}
  </IconButton>
</ListItemSecondaryAction>

我正在尝试做类似的事情,其中​​一个列表项有两个可单击区域,具有两个不同的操作:单击 ListItem(转到页面)或单击 IconButton(展开 ListItem)以显示嵌套的 ListItem。如果没有这个 ListItemSecondaryAction,当我单击一个列表项时,它会路由和展开 ListItem,这是不可取的。

添加SecondaryAction 分隔ListItem 和IconButton 的点击动作。文档不是很好,所以我花了一段时间才理解其目的,但它是here

【讨论】:

  • 谢谢,但我的问题已经解决了。请参阅我原始帖子下方的 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 2022-06-30
  • 2020-07-07
  • 1970-01-01
相关资源
最近更新 更多