Jimbot
Jimbot

Reputation: 716

MUI React menu never get closed

On this MUI AppBar/Drawer sample, I have added a MUI Menu to edit profile, with an anchor on a div. It's located on the top right corner. I like to be able to click on the username or the profile icon to pop the menu out. For some reason the menu never disappear. I have try to add console.log in the callbacks. It shows the open callback is called right after the close one. Can someone explain why and how to close the menu ?

Here is my code, and the full project on Codesandbox :

Edit MenuTest

import React from "react";
import Box from "@mui/material/Box";
import Grid from "@mui/material/Grid";
import IconButton from "@mui/material/IconButton";
import Menu from "@mui/material/Menu";
import MenuIcon from "@mui/icons-material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Toolbar from "@mui/material/Toolbar";
import AccountCircle from "@mui/icons-material/AccountCircle";
import { styled } from "@mui/material/styles";
import { useNavigate } from "react-router-dom";

export default function TopBar(props) {
  const navigate = useNavigate();

  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleMenuOpen = (event) => {
    console.log("set menu open");
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    console.log("set menu close");
    setAnchorEl(null);
  };

  const UserName = styled("div")(({ theme }) => ({
    fontSize: "1em",
    marginRight: "0.7em",
    display: "inline",
    height: "100%",
    textAlign: "center",
    cursor: "pointer"
  }));

  const Logo = styled("img")(({ theme }) => ({
    height: "42px",
    width: "42px",
    backgroundColor: "#FFF",
    marginRight: "0.7em"
  }));

  return (
    <Toolbar>
      <Grid
        style={{ justifyContent: "space-between", alignItems: "center" }}
        container
      >
        <Grid item style={{ display: "inline-flex", alignItems: "center" }}>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={props.handleDrawerOpen}
            edge="start"
            sx={{
              ...(props.drawerOpen && {
                display: {
                  xs: "block",
                  sm: "none"
                }
              })
            }}
          >
            <MenuIcon />
          </IconButton>
        </Grid>
        <Grid item style={{ display: "inline-flex", alignItems: "center" }}>
          <Logo
            src=""
            alt="logo"
            onClick={() => {
              props.handleDrawerClose();
              navigate("/");
            }}
          />
          <Box
            sx={{
              whiteSpace: "nowrap",
              fontSize: { xs: "1em", sm: "1.25em" },
              fontWeight: { xs: 400, sm: 500 }
            }}
          >
            Toolbar test
          </Box>
        </Grid>
        <Grid item style={{ display: "flex", alignItems: "center" }}>
          <div
            style={{ display: "inline-flex", alignItems: "center" }}
            onClick={handleMenuOpen}
          >
            <UserName sx={{ display: { xs: "none", sm: "block" } }}>
              {props.userName}
            </UserName>
            <IconButton
              color="inherit"
              aria-label="user"
              edge="start"
              size="large"
            >
              <AccountCircle />
            </IconButton>
            <Menu
              anchorEl={anchorEl}
              open={Boolean(anchorEl)}
              onClose={handleClose}
            >
              <MenuItem
                onClick={() => {
                  props.handleDrawerClose();
                  navigate("/test");
                }}
              >
                My Profile
              </MenuItem>
              <MenuItem
                onClick={() => {
                  props.handleDrawerClose();
                  navigate("/logout");
                }}
              >
                Logout
              </MenuItem>
            </Menu>
          </div>
        </Grid>
      </Grid>
    </Toolbar>
  );
}

Upvotes: 0

Views: 393

Answers (1)

RedEnum
RedEnum

Reputation: 162

You somehow managed that when you trigger the onClose event, you are simultaneously triggering handleMenuOpen function. I would suggest you use a button base to handle opening the menu. Something like this:

<ButtonBase onClick={handleMenuOpen}>
  <UserName sx={{ display: { xs: "none", sm: "block" } }}>
    {props.userName}
  </UserName>
  <AccountCircle />
</ButtonBase>

And dont forget to remove the onClick event from your div. You can also take a look of the fork that i made.

Upvotes: 1

Related Questions