React 漂亮的 DnD- 嵌套列表,但无需在父列表之间拖动

React beautiful DnD- Nested list, but no need to drag between parent lists

提问人:tprebenda 提问时间:10/5/2021 最后编辑:tprebenda 更新时间:10/6/2021 访问量:1218

问:

我目前正在尝试使用 React Beautiful DnD 创建容器对象的可拖动列表。在这些对象中,我还构建了一个可拖动元素的子列表。我知道该库在技术上不支持嵌套列表,但我已经看到了许多解决方法,我相信我的用例比大多数用例都简单,因为我不需要在父列表项之间拖动子列表项。

到目前为止,我已经创建了一个 DnDList 模块,以便我可以为两个可拖动列表重用代码。下面是 UI 的样子,两个列表都用圆圈圈出(变量名称被涂黑):

图像(尚不可用,我会在清除后分享)

用红色圈出的数字是父列表的一部分,这些列表按预期工作。我可以毫无问题地轻松拖动和重新订购这些更大的 div 容器。然而,用蓝色圈出的列表正在引起问题。

这个子列表由简单的元素组成,我实际上能够拖动和重新排序它们,但是有一个奇怪的问题,我无法连续拖动这些项目。我可以单击一个项目(即)并拖动它一次,但是一旦它被删除,我必须单击父列表中的任何位置,然后才能再次拖动它。在拖动嵌套列表元素后首次单击时,它会错误地尝试拖动周围的父元素并重新排序父列表。但是,单击父列表中的任何内容后,我可以再次拖动子列表组件并重新排序。每次嵌套列表拖动后,都会重复此过程。(奇怪的是,单击父列表之外的按钮不计算在内。也许这种“重置点击”与焦点有关?<p>AlphaCaseStart

这是我的 DnDList 组件的代码:

<DragDropContext onDragEnd={handleDragEnd}>
  <Droppable droppableId={droppableId}>
    {(provided) => (
      <ol
        ref={provided.innerRef}
        {...provided.droppableProps}
        className={classes.root}
      >
        {React.Children.map(
          children,
          (child: React.ReactElement | undefined, index: number) => {
            if (child) {
              const keyVal: string = getAttributeKey(child.props);
              return (
                <Draggable key={keyVal} draggableId={keyVal} index={index}>
                  {(provided, snapshot) => (
                    <li
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                    >
                      {child}
                    </li>
                  )}
                </Draggable>
              );
            }
          }
        )}
        {provided.placeholder}
      </ol>
    )}
  </Droppable>
</DragDropContext>

这是它在使用中的样子:

<DnDList
  handleDragEnd={handleOnDragEnd}
  droppableId="experiments"
  getAttributeKey={getAttributeKey}
>
  {<array>.map(
    (experiment: string, index: number) => (
      <p key={index} className={classes.experiment}>
        {experiment}
      </p>
    )
  )}
</DnDList>

该函数仅返回一个唯一标识符(字符串),用作每个 Draggable 对象的键。getAttributeKey

对于父元素和子列表元素,getAttributeKey 和 handleOnDragEnd 函数实际上是相同的:

const handleOnDragEnd = (result: DropResult) => {
  if (!result.destination) {
    return;
  }
  const newOrder: string[] = Array.from(...);
  const [reorderedItem] = newOrder.splice(result.source.index, 1);
  newOrder.splice(result.destination.index, 0, reorderedItem);

  onChange(...);
};

const getAttributeKey = (props: any) => {
  return props.children;
};

(我删除了所有敏感的变量名称,并将它们替换为“...”)

同样,我什至不需要将子列表元素拖到父列表的另一个元素中,我只需要能够将它们拖到该特定子列表中。

反应JS 嵌套列表 反应-美丽-DND

评论


答: 暂无答案