You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactSortable嵌套组件问题:拖拽元素无法保存至布局块

跨列表拖拽嵌套元素问题修复方案

问题根源

布局块无法保存内部拖拽元素,本质是嵌套元素的状态更新与渲染逻辑未实现:拖拽段落进入layout2的嵌套块时,没有正确定位父布局元素并更新其子元素集合,同时嵌套块也没有渲染内部的子元素。

具体修复步骤

1. 补全元素数据结构

给layout2类型的元素添加children字段,用于存储内部嵌套的元素:

interface Layout2Element {
  id: string;
  type: 'layout2';
  children: Element[];
}

type Element = Layout2Element | ParagraphElement;

2. 修正拖拽事件处理

在onDrop函数中区分普通拖拽和嵌套块拖拽,针对嵌套块的情况,更新对应layout2元素的children:

const onDrop = (e: React.DragEvent, targetId: string, isNested = false) => {
  e.preventDefault();
  const draggedId = e.dataTransfer.getData('text/plain');
  const draggedElement = elements.find(el => el.id === draggedId);
  if (!draggedElement) return;

  if (isNested) {
    // 更新目标layout2的子元素列表
    setEditorElements(prevElements => 
      prevElements.map(el => {
        if (el.type === 'layout2' && el.id === targetId) {
          return { ...el, children: [...el.children, draggedElement] };
        }
        return el;
      })
    );
  } else {
    // 原有拖拽到编辑器根节点的逻辑
    setEditorElements(prev => [...prev, draggedElement]);
  }
};

3. 修复嵌套块渲染逻辑

修改Layout2组件,遍历渲染自身的children元素:

const Layout2 = ({ id, children }: Layout2Element) => {
  return (
    <div className="layout2">
      {/* 第一个嵌套块 */}
      <div 
        className="nested-block"
        onDragOver={(e) => e.preventDefault()}
        onDrop={(e) => onDrop(e, id, true)}
      >
        {children.map(child => 
          child.type === 'paragraph' ? (
            <Paragraph key={child.id} id={child.id} content={child.content} />
          ) : null
        )}
      </div>
      {/* 第二个嵌套块 */}
      <div 
        className="nested-block"
        onDragOver={(e) => e.preventDefault()}
        onDrop={(e) => onDrop(e, id, true)}
      >
        {children.map(child => 
          child.type === 'paragraph' ? (
            <Paragraph key={child.id} id={child.id} content={child.content} />
          ) : null
        )}
      </div>
    </div>
  );
};

4. 初始化布局元素的children

在初始元素数组中给layout2设置空的children数组:

const elements: Element[] = [
  { id: 'layout-1', type: 'layout2', children: [] },
  { id: 'para-1', type: 'paragraph', content: '示例段落1' },
  { id: 'para-2', type: 'paragraph', content: '示例段落2' },
];

效果验证

  1. 将layout2拖拽到编辑器,可见两个空的嵌套块;
  2. 将段落拖拽到任意嵌套块,段落会立即显示在块内,且编辑器的状态会正确保存嵌套元素。

内容的提问来源于stack exchange,提问作者Maxim Gordiyenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:56:29