动态创建React上下文菜单

时间:2017-03-07 22:34:19

标签: javascript reactjs contextmenu react-redux

问题

有没有办法动态创建React组件(或者更具体地说:上下文菜单),即仅当用户请求这样的上下文菜单时?

构建单个上下文菜单的所有必需信息已经存在于触发它的组件上,这意味着无需等待任何异步提取数据。

在其他情况下,这很容易实现,但我无法理解如何在React + Redux应用程序中完成此操作。

在编写此文件时,唯一想到的就是在触发上下文菜单时发送操作,并将此单个上下文菜单包含在生成的重新呈现中的某种弹出对话框中。

这至少可以避免过早创造大量无形组件。但它有点像反模式。我在这里缺少什么?

背景

我的React应用程序中显示的状态是一个层次结构,实际上嵌套了六到七个深度。

在顶层,它是一个简单的列表。但是每个列表项都有这样的结构:

Item = {
    priorChildren: List<Item>
    content: List<NonHierarchicalData>
    laterChildren: List<Item>
}

这些Item可以以用户认为合适的任何方式嵌套。

  • 每个Item应该通过上下文菜单提供最多五个操作,具体取决于它在层次结构中的位置(可能不超过10个排列)。
  • 每个NonHierarchicalData还应提供一个上下文菜单,具体取决于其数据,最多可能包含30个菜单项。由于数据包含合并到菜单项中的用户输入,因此每个上下文菜单都可能是唯一的。

现实状态可能包含大约30或40个这些Item个,每个都有5到10个NonHierarchicalData元素。基于这些数字,我最终可以得到ca. 250种不同的上下文菜单,包含5000多个菜单项。 在任何给定时间,用户可能只会在选择动作之前打开一个或两个上下文菜单,从而触发状态更改,从而重新渲染。

挑战

一方面,有很好的现有库,如react-contextmenu,它们希望所有上下文菜单变体都是预先知道的,并且只能在需要时才能显示为DOM的一部分。

另一方面,在下一次状态改变之后不可避免地重新创建它们之前,创建数百个具有数千个条目的菜单只是为了显示几十个条目,这感觉是违反直觉的。

2 个答案:

答案 0 :(得分:4)

从版本v2.3.1开始,react-contextmenu提供connectMenu()帮助程序,以便能够将触发器的道具传递到单个注册菜单,以便更改其渲染 但是,将来可能会对其进行重构,因此在较新版本中请谨慎使用。

简而言之:您可以为ContextMenu创建一个包装器组件,并通过上述connectMenu()帮助器使其能够接收它的触发器道具。

const MENU_ID = 'some-identifier';
const DynamicMenu = (props) => {
  const { id, trigger } = props;
  return (
    <ContextMenu id={id}>
      {trigger && <MenuItem>{trigger.itemLabel}</MenuItem>}
    </ContextMenu>
  );
};
const ConnectedMenu = connectMenu(MENU_ID)(DynamicMenu);

ContextMenu(此处为ConnectedMenu)的此连接包装只需在一些父组件中包含一次,而多个触发器可将其用于具有不同内容的菜单。请注意ContextMenuTrigger的{​​{1}}道具必须转发其所有connect或至少与正在构建的菜单相关的部分。 E.g。

props

有关完整示例,请参阅项目的DynamicMenu demo

答案 1 :(得分:0)

这里是处理可继承菜单的替代方法;

此lib允许子组件中的菜单也可以在其上下文中显示父菜单,可以选择基于浏览器事件和父菜单。

202

查看演示https://github.com/n8tz/react-inheritable-context-menu