为什么我的 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。

我想通了:

每个 ContextMenuTriggerContextMenuid 必须匹配,他们做到了。但是由于我在列表中动态生成所有内容,列表中的每个元素都使用相同的 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>
  );