Material-UI菜单组件仅触发最后一个MenuItem onClick操作

时间:2019-09-21 16:04:52

标签: reactjs material-ui

最近,我尝试使用MaterialUI(4.3.3)的Menu和MenuItem组件实现一个简单的下拉菜单。

MenuItem上的onclick事件行为不正确。调用console.log(id)时,每个组件都在回显样本数组中的最后一个元素。我切换到ListItem,问题消失了。


const Test = () => {
    const [anchorEl, setAnchorEl] = React.useState(null);
    const sampleArray = ["test1", "test2", "test3"];
    const open = Boolean(anchorEl);

    return (
        sampleArray.map(id => {
            let curID = id;
            return (<>
                <IconButton
                    aria-label="more"
                    aria-controls="long-menu"
                    aria-haspopup="true"
                    onClick={event => setAnchorEl(event.currentTarget)}
                >
                    <MoreHorizIcon />
                </IconButton>
                <Menu
                    elevation={0}
                    id="long-menu"
                    anchorEl={anchorEl}
                    keepMounted
                    open={open}
                    transformOrigin={{
                        vertical: 'top',
                        horizontal: 'center',
                    }}
                    onClose={() => setAnchorEl(null)}
                >
                    <MenuItem onClick={() => {
                        setAnchorEl(null);
                        console.log(curID); // should be each individual id, but here always "test3"
                    }}>Test</MenuItem>
                </Menu>
            </>);
        })
    )
}

这是Menu的预期行为吗?如何解决?

1 个答案:

答案 0 :(得分:0)

是的,这是所需的行为。有点令人困惑:
您具有单一状态(anchorEl),该状态决定所有菜单的锚点。
当您单击IconButton时,可以将相同的AnchorEl设置到所有菜单。
因此,当您打开菜单时,实际上是在同一位置打开了所有三个菜单!
您总是在控制台中得到“ test3”的原因是因为ID为test3的菜单最后呈现,并且他与其他菜单重叠。


要解决此问题,您需要每个菜单来管理其自身的状态,因此每个菜单都将具有其自己的锚点:

const IsolatedMenu = props => {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const open = Boolean(anchorEl);

  return(
  <React.Fragment>
    <IconButton
    aria-label="more"
    aria-controls="long-menu"
    aria-haspopup="true"
    onClick={event => setAnchorEl(event.currentTarget)}
    >
    <PriorityHighIcon />
    </IconButton>
    <Menu
    elevation={0}
    id="long-menu"
    anchorEl={anchorEl}
    keepMounted
    open={open}
    transformOrigin={{
        vertical: 'top',
        horizontal: 'center',
    }}
    onClose={() => setAnchorEl(null)}
    >
    <MenuItem onClick={() => {
        setAnchorEl(null);
        console.log('curr id',props.id); // should be each individual id, but here always "test3"
    }}>Test</MenuItem>
    </Menu>

  </React.Fragment>
  )
}

然后您的Test组件应如下所示:

const Test = () => {
  const sampleArray = ["test1", "test2", "test3"];

  return (
      sampleArray.map(id => {
          return (<>
            <IsolatedMenu  id={id}/>
          </>);
      })
  )
}

Edit Invisible Backdrop