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

使用Beautiful DnD开发Web应用:最后元素拖出后列消失的解决求助

解决Beautiful DnD移除最后一个元素后列消失的问题

问题根源

你大概率是把列的渲染逻辑和列内元素列表的长度绑定了——比如仅当column.items.length > 0时才渲染列组件,这就导致最后一个元素被拖走后列直接不渲染了。

具体解决方案

1. 分离列的存在与元素列表的关联

直接去掉基于元素数量的渲染判断,无论列内有没有元素,都保留列的渲染:

// 错误写法:元素为空时不渲染列
{columns.map(column => 
  column.items.length > 0 && (
    <Column key={column.id} column={column} />
  )
)}

// 正确写法:始终渲染列
{columns.map(column => 
  <Column key={column.id} column={column} />
)}

2. 在列组件内处理空状态

列内无元素时,保留列的结构,同时添加空状态提示和Beautiful DnD必需的占位符:

function Column({ column }) {
  return (
    <div className="column-container">
      <h3>{column.title}</h3>
      <Droppable droppableId={column.id}>
        {(provided) => (
          <div
            {...provided.droppableProps}
            ref={provided.innerRef}
            className="droppable-area"
          >
            {column.items.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    className="card"
                  >
                    {item.content}
                  </div>
                )}
              </Draggable>
            ))}
            {/* 必须保留:Beautiful DnD用来计算拖拽位置的占位符 */}
            {provided.placeholder}
            {/* 自定义空状态提示,可选 */}
            {column.items.length === 0 && (
              <div className="empty-hint">暂无卡片,可拖拽至此</div>
            )}
          </div>
        )}
      </Droppable>
    </div>
  );
}

3. 调整拖拽结束后的状态更新逻辑

确保移除最后一个元素时,仅清空列的items数组,不删除列对象本身:

function handleDragEnd(result) {
  if (!result.destination) return;

  const { source, destination } = result;
  if (source.droppableId === destination.droppableId && source.index === destination.index) return;

  // 复制原数据,避免直接修改状态
  const newColumns = [...columns];
  const sourceCol = {...newColumns.find(col => col.id === source.droppableId)};
  const destCol = {...newColumns.find(col => col.id === destination.droppableId)};

  // 移动元素
  const [movedItem] = sourceCol.items.splice(source.index, 1);
  destCol.items.splice(destination.index, 0, movedItem);

  // 更新列数据:即使源列items为空,仍保留列对象
  newColumns[newColumns.findIndex(col => col.id === source.droppableId)] = sourceCol;
  newColumns[newColumns.findIndex(col => col.id === destination.droppableId)] = destCol;

  setColumns(newColumns);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:55:20