如何将数据传递给MenuItem事件处理程序



当我有一个数组并为数组中的每个元素呈现一个Menu时,项目的单击处理程序只接收数组中的最后一个元素,而不是用于该呈现的元素。

这里的用例是有一个项目列表,其中每个项目都有一个菜单来执行特定于该项目的操作,如"删除"、"编辑"等。

不工作示例:https://codesandbox.io/s/material-demo-forked-u6902?file=/demo.js

export default function SimpleMenu() {
const [anchor, setAnchor] = React.useState(null);
const handleOpenMenu = (event) => {
setAnchor(event.currentTarget);
};
const handleCloseMenu = (number) => {
console.log(number);
setAnchor(null);
};
return ["one", "two"].map((number) => (
<div key={number}>
<Button onClick={() => handleCloseMenu(number)}>Log {number}</Button>
<Button onClick={(e) => handleOpenMenu(e)}>Menu {number}</Button>
<Menu
anchorEl={anchor}
keepMounted
open={Boolean(anchor)}
onClose={() => handleCloseMenu(number)}
>
<MenuItem onClick={() => handleCloseMenu(number)}>Log Number</MenuItem>
</Menu>
</div>
));
}

但是,如果我在内存中保留数组元素到菜单锚的映射,那么它就会像预期的那样工作。

工作示例:https://codesandbox.io/s/material-demo-forked-m7utx?file=/demo.js

export default function SimpleMenu() {
const [anchors, setAnchors] = React.useState({});
const handleOpenMenu = (number, event) => {
setAnchors((prevState) => ({
...prevState,
[number]: event.currentTarget
}));
};
const handleCloseMenu = (number) => {
console.log(number);
setAnchors((prevState) => ({
...prevState,
[number]: null
}));
};
return ["one", "two"].map((number) => (
<div key={number}>
<Button onClick={() => handleCloseMenu(number)}>Log {number}</Button>
<Button onClick={(e) => handleOpenMenu(number, e)}>Menu {number}</Button>
<Menu
anchorEl={anchors[number]}
keepMounted
open={Boolean(anchors[number])}
onClose={() => handleCloseMenu(number)}
>
<MenuItem onClick={() => handleCloseMenu(number)}>Log Number</MenuItem>
</Menu>
</div>
));
}

这是正确的或预期的方式来呈现多个菜单?

在你的第一个例子中:因为所有的菜单'open' prop是相同的锚状态,你在同一时间打开它们。因此,只有最后一项显示,因为它在顶部。

第二个有效,因为您只访问每个'number'的state属性,并且一次只有一个菜单是'打开'的。这似乎是一个很好的解决方案,因为由于'ClickAway'事件,用户无法打开其他菜单。

下面是解决这个问题的另一个非常基本的例子。其中每个菜单只有在其编号当前被选中时才会"打开"。

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";
export default function SimpleMenu() {
const [anchor, setAnchor] = React.useState(null);
const [currentNumber, setCurrentNumber] = React.useState(null);
const handleOpenMenu = (event, number) => {
setAnchor(event.currentTarget);
setCurrentNumber(number);
};
const handleCloseMenu = (number) => {
console.log(number);
setAnchor(null);
setCurrentNumber(null);
};
return ["one", "two"].map((number) => (
<div key={number}>
<Button onClick={() => handleCloseMenu(number)}>Log {number}</Button>
<Button onClick={(e) => handleOpenMenu(e, number)}>Menu {number}</Button>
<Menu
anchorEl={anchor}
keepMounted
open={currentNumber === number}
onClose={() => handleCloseMenu(number)}
>
<MenuItem onClick={() => handleCloseMenu(number)}>Log {number}</MenuItem>
</Menu>
</div>
));
}

最新更新