为什么我的 react-contextmenu 列表中的每个 MenuItem 都是相同的?
Why is each MenuItem in my react-contextmenu list identical?
作为参考,我正在使用 react-contextmenu 将上下文菜单添加到我的应用程序。
我在列表中有项目,您可以右键单击每个项目以对其执行一些操作。每个项目都提供了一个上下文菜单,它也是一个列表,因此我的代码中有几个 map
方法。 (我确保根据信息 here and here 使用唯一键)。然而,这是我观察到的行为(右键单击列表中的任何项目 always 显示列表中最后一项的上下文菜单):
这是我的代码:
function ListItem(props) {
// console.log(`CONTEXT OPTIONS for ${props.name}:\n${JSON.stringify(props.contextOptions)}`);
// console.log(`Mapped context options for ${props.name}:\n${props.contextOptions.map((option) => option.label + option.subLabel)}`);
const contextOptions = props.contextOptions.map((option) =>
<MenuItem
key={option.label + option.subLabel}
disabled={option.disabled}
divider={option.divider}>
{option.label}<span className="context-sublabel">{option.subLabel}</span>
</MenuItem>
);
return (
<div>
<ContextMenuTrigger id="list-item-context">
<div className={"list-item-container" + (props.selected ? " list-item-selected" : "")}
onClick={ () => props.onSelection(props.index) } >
<p className="list-item-label">{props.name}</p>
</div>
</ContextMenuTrigger>
<ContextMenu id="list-item-context">
{contextOptions}
</ContextMenu>
</div>
);
}
我什至把打印语句到处扔,以确保我不会以某种方式传递相同上下文菜单信息的列表。例如,有一次我这样写地图:
const contextOptions = props.contextOptions.map((option) => {
console.log(`Item: ${props.name}, label: ${option.label}, sub-label: ${option.subLabel}`);
return (<MenuItem
key={option.label + option.subLabel}
disabled={option.disabled}
divider={option.divider}>
{option.label}<span className="context-sublabel">{option.subLabel}</span>
</MenuItem>);
});
输出证明我的数据是正确的:
Item: ITEM A, label: Copy "ITEM A", sub-label:
Item: ITEM A, label: , sub-label:
Item: ITEM A, label: Connect, sub-label: - [PRIMARY IP A]
Item: ITEM A, label: Connect, sub-label: - [BACKUP IP A]
Item: ITEM B, label: Copy "ITEM B", sub-label:
Item: ITEM B, label: , sub-label:
Item: ITEM B, label: Connect, sub-label: - [PRIMARY IP B]
Item: ITEM B, label: Connect, sub-label: - [BACKUP IP B]
Item: ITEM C, label: Copy "ITEM C", sub-label:
Item: ITEM C, label: , sub-label:
Item: ITEM C, label: Connect, sub-label: - [PRIMARY IP C]
Item: ITEM C, label: Connect, sub-label: - [BACKUP IP C]
注意:空标签或子标签在我的应用程序上下文中没有问题。
我实在想不通为什么 UI 实际呈现的文本没有显示正确的文本。也许它不受支持?我看到的这个库被使用的每个例子都明确地写出了 MenuItem
JSX。
我想通了:
每个 ContextMenuTrigger
和 ContextMenu
的 id
必须匹配,他们做到了。但是由于我在列表中动态生成所有内容,列表中的每个元素都使用相同的 id,因此它们都显示相同的数据。为了使我的 ID 独一无二,我在它们后面附加了名称属性,因为在我的应用程序的上下文中,名称保证是唯一的:
return (
<div>
<ContextMenuTrigger id={"list-item-context" + `-${props.name}`}>
<div className={"list-item-container" + (props.selected ? " list-item-selected" : "")}
onClick={ () => props.onSelection(props.index) } >
<p className="list-item-label">{props.name}</p>
</div>
</ContextMenuTrigger>
<ContextMenu id={"list-item-context" + `-${props.name}`}>
{contextOptions}
</ContextMenu>
</div>
);
作为参考,我正在使用 react-contextmenu 将上下文菜单添加到我的应用程序。
我在列表中有项目,您可以右键单击每个项目以对其执行一些操作。每个项目都提供了一个上下文菜单,它也是一个列表,因此我的代码中有几个 map
方法。 (我确保根据信息 here and here 使用唯一键)。然而,这是我观察到的行为(右键单击列表中的任何项目 always 显示列表中最后一项的上下文菜单):
这是我的代码:
function ListItem(props) {
// console.log(`CONTEXT OPTIONS for ${props.name}:\n${JSON.stringify(props.contextOptions)}`);
// console.log(`Mapped context options for ${props.name}:\n${props.contextOptions.map((option) => option.label + option.subLabel)}`);
const contextOptions = props.contextOptions.map((option) =>
<MenuItem
key={option.label + option.subLabel}
disabled={option.disabled}
divider={option.divider}>
{option.label}<span className="context-sublabel">{option.subLabel}</span>
</MenuItem>
);
return (
<div>
<ContextMenuTrigger id="list-item-context">
<div className={"list-item-container" + (props.selected ? " list-item-selected" : "")}
onClick={ () => props.onSelection(props.index) } >
<p className="list-item-label">{props.name}</p>
</div>
</ContextMenuTrigger>
<ContextMenu id="list-item-context">
{contextOptions}
</ContextMenu>
</div>
);
}
我什至把打印语句到处扔,以确保我不会以某种方式传递相同上下文菜单信息的列表。例如,有一次我这样写地图:
const contextOptions = props.contextOptions.map((option) => {
console.log(`Item: ${props.name}, label: ${option.label}, sub-label: ${option.subLabel}`);
return (<MenuItem
key={option.label + option.subLabel}
disabled={option.disabled}
divider={option.divider}>
{option.label}<span className="context-sublabel">{option.subLabel}</span>
</MenuItem>);
});
输出证明我的数据是正确的:
Item: ITEM A, label: Copy "ITEM A", sub-label:
Item: ITEM A, label: , sub-label:
Item: ITEM A, label: Connect, sub-label: - [PRIMARY IP A]
Item: ITEM A, label: Connect, sub-label: - [BACKUP IP A]
Item: ITEM B, label: Copy "ITEM B", sub-label:
Item: ITEM B, label: , sub-label:
Item: ITEM B, label: Connect, sub-label: - [PRIMARY IP B]
Item: ITEM B, label: Connect, sub-label: - [BACKUP IP B]
Item: ITEM C, label: Copy "ITEM C", sub-label:
Item: ITEM C, label: , sub-label:
Item: ITEM C, label: Connect, sub-label: - [PRIMARY IP C]
Item: ITEM C, label: Connect, sub-label: - [BACKUP IP C]
注意:空标签或子标签在我的应用程序上下文中没有问题。
我实在想不通为什么 UI 实际呈现的文本没有显示正确的文本。也许它不受支持?我看到的这个库被使用的每个例子都明确地写出了 MenuItem
JSX。
我想通了:
每个 ContextMenuTrigger
和 ContextMenu
的 id
必须匹配,他们做到了。但是由于我在列表中动态生成所有内容,列表中的每个元素都使用相同的 id,因此它们都显示相同的数据。为了使我的 ID 独一无二,我在它们后面附加了名称属性,因为在我的应用程序的上下文中,名称保证是唯一的:
return (
<div>
<ContextMenuTrigger id={"list-item-context" + `-${props.name}`}>
<div className={"list-item-container" + (props.selected ? " list-item-selected" : "")}
onClick={ () => props.onSelection(props.index) } >
<p className="list-item-label">{props.name}</p>
</div>
</ContextMenuTrigger>
<ContextMenu id={"list-item-context" + `-${props.name}`}>
{contextOptions}
</ContextMenu>
</div>
);