简体   繁体   中英

How do I make separate Menu/MenuItem in a React/MUI navbar?

I'm making a navbar for an application and am having some trouble with separating multiple Menu/MenuItem. Whatever I try, both Menus and their MenuItems link to the same place.

Here's my code:


import { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem'; 

const Navbar = (props) => {
    const navigate = useNavigate();

    const logout = () => {
        props.onAuthenticated(false);
        navigate('/');
    };

    const [anchorEl, setAnchorEl] = useState(null);
    const open = Boolean(anchorEl);

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

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

    return (
        <Grid item xs={12}>
            <Button component={Link} to='/'>Home</Button>
            <Button
                id="basic-button-1"
                aria-controls={open ? 'basic-menu-1' : undefined}
                aria-haspopup="true"
                aria-expanded={open ? 'true' : undefined}
                onClick={handleClick}
            >
                Movies
            </Button>
            <Button
                id="basic-button-2"
                aria-controls={open ? 'basic-menu-2' : undefined}
                aria-haspopup="true"
                aria-expanded={open ? 'true' : undefined}
                onClick={handleClick}
            >
                Actors
            </Button>
            <Menu
                id="basic-menu-1"
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                MenuListProps={{
                'aria-labelledby': 'basic-button-1',
                }}
            >
                <MenuItem component={Link} to='/movies' onClick={handleClose}>All</MenuItem>
                <MenuItem component={Link} to='/movies/create' onClick={handleClose}>Create</MenuItem>
            </Menu>
            <Menu
                id="basic-menu-2"
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                MenuListProps={{
                'aria-labelledby': 'basic-button-2',
                }}
            >
                <MenuItem component={Link} to='/actors' onClick={handleClose}>All</MenuItem>
                <MenuItem component={Link} to='/actors/create' onClick={handleClose}>Create</MenuItem>
            </Menu>

            {(props.authenticated) ? (
                <Button variant='outlined' onClick={logout}>Logout</Button>
            ) : ""}

        </Grid>
    );
};

export default Navbar;

In the above code, the NavBar created contains a 'Home', 'Movies' and 'Actors' headings, and the 'Movies' and 'Actors' dropdowns work, but both of them link to the /actors pages. I tried a few things like creating separate anchorEls, opens and handlers, but that actually reversed the problem, and both 'Movies' and 'Actors' started linking to /movies rather than /actors. I can't seem to get them both to link to where they're supposed to go, and I can't help but think I'm missing something simple.

If anyone knows what I'm doing wrong, I'd appreciate the help. Thanks.

One way to do it would be to dynamically set the anchors depending on the buttons name.

States / functions:

 const [anchorState, setAnchorState] = useState({
    btn1: null,
    btn2: null,
  });

  const handleClick = (e) => {
    setAnchorState({ [e.target.name]: e.currentTarget });
  };

  const handleClose = (e) => {
    setAnchorState({ [e.target.name]: null });
  };

Buttons:

      <Button
        id="basic-button-1"
        aria-controls={Boolean(anchorState.btn1) ? "basic-menu-1" : undefined}
        aria-haspopup="true"
        aria-expanded={Boolean(anchorState.btn1) ? "true" : undefined}
        onClick={handleClick}
        name="btn1"
      >
        Movies
      </Button>

      <Button
        id="basic-button-2"
        aria-controls={Boolean(anchorState.btn2) ? "basic-menu-2" : undefined}
        aria-haspopup="true"
        aria-expanded={Boolean(anchorState.btn2) ? "true" : undefined}
        onClick={handleClick}
        name="btn2"
      >
        Actors
      </Button>

Menus:

      <Menu
        id="basic-menu-1"
        anchorEl={anchorState.btn1}
        open={Boolean(anchorState.btn1)}
        onClose={handleClose}
        MenuListProps={{
          "aria-labelledby": "basic-button-1",
        }}
      >
        <MenuItem component={Link} to="/movies" onClick={handleClose}>
          All
        </MenuItem>
        <MenuItem component={Link} to="/movies/create" onClick={handleClose}>
          Create
        </MenuItem>
      </Menu>
      <Menu
        id="basic-menu-2"
        anchorEl={anchorState.btn2}
        open={Boolean(anchorState.btn2)}
        onClose={handleClose}
        MenuListProps={{
          "aria-labelledby": "basic-button-2",
        }}
      >
        <MenuItem component={Link} to="/actors" onClick={handleClose}>
          All
        </MenuItem>
        <MenuItem component={Link} to="/actors/create" onClick={handleClose}>
          Create
        </MenuItem>
      </Menu>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM