react 中 `ondrop` 事件在 `
` 上不触发,根本原因是浏览器默认阻止了 `dragover` 事件的默认行为,导致后续 `drop` 无法触发;必须显式添加 `ondragover` 并调用 `e.preventdefault()` 才能启用拖放目标功能。在原代码中,你已正确绑定了 onDragStart、onDragEnter、onDragLeave 和 onDrop,但遗漏了关键的 onDragOver 处理函数。根据 HTML5 拖放规范,一个元素要成为有效的拖放目标(即能接收 drop 事件),必须:
✅ 正确做法是在每个可接收拖入的
容器上添加 onDragOver,而非仅在卡片()上——因为你的目标是将卡片拖入“列表区域”(TODO 或 COMPLETED 列),而不是拖到另一个卡片上。以下是修复后的关键修改(仅展示需调整的部分):
e.preventDefault()} // ✅ 必须添加!
onDrop={(e) => handleDrop(e, 'TODO')}>
TODO
{cards
.filter((c) => c.list === 'TODO')
.map((card) => (
handleDragStart(e, card.id)}
// 注意:此处移除卡片上的 onDrop/onDragOver —— 它们不是 drop 目标
>
{card.title}
))}
e.preventDefault()} // ✅ 同样必须添加
onDrop={(e) => handleDrop(e, 'COMPLETED')}>
COMPLETED
{cards
.filter((c) => c.list === 'COMPLETED')
.map((card) => (
handleDragStart(e, card.id)}
>
{card.title}
))}
⚠️ 重要注意事项:
agOver 中仅需 e.preventDefault(),无需其他逻辑(如 setData),它纯粹是“声明该区域可接收拖放”的信号;? 总结:HTML5 拖放是“三步协议”——dragstart → dragover(必须 preventDefault)→ drop。缺一不可。React 中只需确保目标容器拥有 onDragOver={(e) => e.preventDefault()},即可让 onDrop 稳定触发。无需第三方库,纯原生能力即可实现健壮的看板式拖放交互。