Material-UI菜单组件仅触发了最后一个MenuItem onClick操作 [英] Material-UI Menu component only last MenuItem onClick action is triggered

查看:79
本文介绍了Material-UI菜单组件仅触发了最后一个MenuItem onClick操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Recently I tried to implement a simple dropdown menu using MaterialUI(4.3.3)'s Menu and MenuItem components.

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

The onclick event on the MenuItem is not behaving correctly. When console.log(id) is called, every component is echoing the last element from sample array. I switched to ListItem, the problem is gone.


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的预期行为吗?如何解决?

Is this the desired behavior for Menu? How to resolve it?

推荐答案

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

Yes, this is the desired behavior. It's a little confusing:
You have single state (anchorEl), which decides what is the anchor for all menus.
When you click on a IconButton, you set the same AnchorEl to all menus.
So when you open the menu, you actually open all 3 menus in the same place!
The reason you always get 'test3' in the console, is because menu with the id test3 is rendered last and he overlaps the other menus.

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

To fix this, you need every menu to manage it's own state, so every menu will have it's own anchor:

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组件应该看起来像这样:

And than your Test component should look like that:

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

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

这篇关于Material-UI菜单组件仅触发了最后一个MenuItem onClick操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆