最近,我尝试使用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的预期行为吗?如何解决?
答案 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}/>
</>);
})
)
}