Material-UI Menu 组件仅触发最后一个 MenuItem onClick 动作

IT技术 reactjs material-ui
2021-04-30 20:54:51

最近我尝试使用 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个回答

是的,这是所需的行为。这有点令人困惑:
您有单个状态 (anchorEl),它决定了所有菜单的锚点
当您单击 IconButton 时,您为所有菜单设置了相同的 AnchorEl。
所以当你打开菜单时,你实际上是在同一个地方打开了所有 3 个菜单!
你总是在控制台中得到 '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}/>
          </>);
      })
  )
}

编辑隐形背景