拖拽时 DataTransfer 的 setData 为什么在 onDragStart 里没生效?

程序员绍博 阅读 356

我在 React 里做拖拽功能,想通过 setData 传一个自定义 ID,但 drop 的时候用 getData 拿不到值,一直是空字符串。是不是我写法有问题?

试过把 e.dataTransfer.dropEffect = 'move' 加上也没用,控制台也不报错,就是取不到数据。

const handleDragStart = (e, id) => {
  e.dataTransfer.setData('text/plain', id);
};

const handleDrop = (e) => {
  const id = e.dataTransfer.getData('text/plain');
  console.log('dropped id:', id); // 这里总是空
};
我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
Mr-志利
Mr-志利 Lv1
你漏了 dragover 事件里阻止默认行为,浏览器默认是不允许 drop 的,所以 dataTransfer 数据被清空了。

在 drop 目标元素上加上这个:

const handleDragOver = (e) => {
e.preventDefault(); // 这行不能少
};

// drop 目标元素


没有 dragoverpreventDefault(),drop 事件根本不会正常触发,setData 的数据自然也拿不到。这是 HTML5 拖拽 API 最容易踩的坑。
点赞
2026-03-01 23:33
一士娇
一士娇 Lv1
我之前也碰到过这个坑,折腾了好久才发现问题所在。

你检查一下有没有写 onDragOver 事件处理,并且在里面调用 e.preventDefault()。这个是必须的,否则浏览器默认行为会阻止 drop 事件正常触发,就算触发了 getData 也可能拿到空值。

要这样写:

const handleDragOver = (e) => {
e.preventDefault(); // 这一行很关键,不能省
e.dataTransfer.dropEffect = 'move';
};

const handleDrop = (e) => {
e.preventDefault(); // 这里也要阻止默认行为
const id = e.dataTransfer.getData('text/plain');
console.log('dropped id:', id);
};


然后你的放置目标元素要绑定 onDragOver



另外还有个常见的坑,在 React 里有时候 dataTransfer 的数据会莫名其妙丢掉。如果上面都对了还是不行,可以用 useRef 来绕一下,简单粗暴但管用:

const dragIdRef = useRef(null);

const handleDragStart = (e, id) => {
dragIdRef.current = id; // 直接存 ref 里
e.dataTransfer.setData('text/plain', id);
};

const handleDrop = (e) => {
e.preventDefault();
const id = dragIdRef.current; // 从 ref 取
console.log('dropped id:', id);
};


先试试加 onDragOverpreventDefault(),大概率是这个问题。
点赞 1
2026-03-01 16:36