首页 > 解决方案 > 我可以包括材质 UI 中的菜单项

零件?

问题描述

我的 AppBar 中有一个菜单,当有空间时,我希望某些项目在 AppBar 上显示为按钮,而在现有菜单中没有空间时显示为菜单项。也就是说,菜单始终存在并且始终包含项目。我只是希望某些功能成为 AppBar 按钮或菜单项,具体取决于屏幕大小。

这是一个简化的示例:

<Menu
  id="settings-menu"
  anchorEl={anchorEl}
  open={Boolean(anchorEl)}
  onClose={handleClose}
>
  <Hidden lgUp>
    <MenuItem onClick={logout}>
      <ListItemIcon><ExitToAppIcon /></ListItemIcon>
      <ListItemText primary="Hidden log out" />
    </MenuItem>
  </Hidden>
  <MenuItem onClick={logout}>
    <ListItemIcon><ExitToAppIcon /></ListItemIcon>
    <ListItemText primary="Log out" />
  </MenuItem>
</Menu>

当我打开菜单时,我在控制台中收到一条错误消息:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `ForwardRef(Menu)`.
    in Hidden (at NavBar.js:76)
    in ul (created by ForwardRef(List))
    in ForwardRef(List) (created by WithStyles(ForwardRef(List)))
    in WithStyles(ForwardRef(List)) (created by ForwardRef(MenuList))
    in ForwardRef(MenuList) (created by ForwardRef(Menu))
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by Transition)
    in Transition (created by ForwardRef(Grow))
    in ForwardRef(Grow) (created by TrapFocus)
    in TrapFocus (created by ForwardRef(Modal))
    in div (created by ForwardRef(Modal))
    in ForwardRef(Portal) (created by ForwardRef(Modal))
    in ForwardRef(Modal) (created by ForwardRef(Popover))
    in ForwardRef(Popover) (created by WithStyles(ForwardRef(Popover)))
    in WithStyles(ForwardRef(Popover)) (created by ForwardRef(Menu))
    in ForwardRef(Menu) (created by WithStyles(ForwardRef(Menu)))
    in WithStyles(ForwardRef(Menu)) (at NavBar.js:70)
    in div (at NavBar.js:50)
    in div (created by ForwardRef(Toolbar))
    in ForwardRef(Toolbar) (created by WithStyles(ForwardRef(Toolbar)))
    in WithStyles(ForwardRef(Toolbar)) (at NavBar.js:48)
    in header (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by ForwardRef(AppBar))
    in ForwardRef(AppBar) (created by WithStyles(ForwardRef(AppBar)))
    in WithStyles(ForwardRef(AppBar)) (at NavBar.js:47)
    in Header (at Layout.js:32)
    in div (at Layout.js:31)
    in div (at Layout.js:29)
    in Layout (at App.js:18)
    in Unknown (at src/index.js:39)
    in Router (at src/index.js:38)
    in ThemeProvider (at src/index.js:37)
    in Provider (at src/index.js:36)

是否<Hidden>允许在<Menu>? 如果不是,那么允许菜单项根据屏幕大小有条件地出现的好方法是什么?

标签: reactjsmaterial-ui

解决方案


由于错误表明Hidden不支持接收 ref 并且这是菜单项所必需的。

但是,您可以使用以下方法实现相同的目的Box

import React from "react";
import Button from "@material-ui/core/Button";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import Box from "@material-ui/core/Box";

export default function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

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

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

  return (
    <div>
      <Button
        aria-controls="simple-menu"
        aria-haspopup="true"
        onClick={handleClick}
      >
        Open Menu
      </Button>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <MenuItem onClick={handleClose}>Always Displayed</MenuItem>
        <Box clone display={{ sm: "none" }}>
          <MenuItem onClick={handleClose}>Profile</MenuItem>
        </Box>
        <Box clone display={{ lg: "none" }}>
          <MenuItem onClick={handleClose}>My account</MenuItem>
        </Box>
        <Box clone display={{ md: "none" }}>
          <MenuItem onClick={handleClose}>Logout</MenuItem>
        </Box>
      </Menu>
    </div>
  );
}

编辑隐藏的菜单项

不幸的是,Box在这种情况下,使用可能会很脆弱,因为它覆盖了被包装组件设置的样式,因为导入顺序会影响哪一个获胜(请参阅此处的进一步讨论:Box vs className vs style for vertical spacing in Material UI)。

另一种选择是使用在特定断点处withStyles创建隐藏版本:MenuItem

import React from "react";
import Button from "@material-ui/core/Button";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import { withStyles } from "@material-ui/core/styles";

const MenuItemHiddenLgUp = withStyles(theme => ({
  root: {
    [theme.breakpoints.up("lg")]: {
      display: "none"
    }
  }
}))(MenuItem);

export default function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

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

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

  return (
    <div>
      <Button
        aria-controls="simple-menu"
        aria-haspopup="true"
        onClick={handleClick}
      >
        Open Menu
      </Button>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <MenuItem onClick={handleClose}>Always Displayed</MenuItem>
        <MenuItemHiddenLgUp onClick={handleClose}>Profile</MenuItemHiddenLgUp>
        <MenuItemHiddenLgUp onClick={handleClose}>
          My account
        </MenuItemHiddenLgUp>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
    </div>
  );
}

编辑隐藏的菜单项

文档:


推荐阅读