React应用在IE/Edge中使用dataTransfer的getData/setData报错求助
dataTransfer Issues in IE & Edge Hey there, let's break down exactly what's going on here—those two errors are absolutely linked, and they're classic gotchas with how older versions of IE and Edge handle the dataTransfer API (Chrome is way more forgiving!).
Why You're Seeing These Errors
Let's connect the dots clearly:
- "Element not found" error: This stems from strict rules IE/Edge enforce for
dataTransfermethods:setData()must be called synchronously inside thedragstartevent handler—you can't call it later (like in an async function or unrelated event).getData()can only be accessed in thedropevent. Calling it indragover,dragend, or any other event will throw this error.
- JSON.parse error: When the first error occurs,
getData()returns an empty string instead of your expected data. Trying to parse an empty string withJSON.parse()will always trigger that "Unexpected input" error.
Step-by-Step Fixes
Here's how to adjust your React code to play nice with IE/Edge:
1. Use the Native Event for dataTransfer
React's synthetic event can sometimes wrap dataTransfer in a way that breaks in older browsers. Always access the native event directly with e.nativeEvent:
const handleDragStart = (e) => { // Grab the raw browser event instead of React's synthetic wrapper const nativeDragEvent = e.nativeEvent; };
2. Restrict setData() to dragstart (Synchronously!)
Set your data immediately in the dragstart handler, and use a MIME type IE recognizes (stick with text/plain for widest compatibility—stringify your JSON data to store it here):
const handleDragStart = (e) => { const nativeDragEvent = e.nativeEvent; // Stringify your data to store as plain text const payload = JSON.stringify({ itemId: 123, content: "Drag this item" }); // Set data synchronously in dragstart (no async calls here!) nativeDragEvent.dataTransfer.setData("text/plain", payload); // Optional: Define allowed drag behavior nativeDragEvent.dataTransfer.effectAllowed = "move"; };
3. Only Call getData() in drop (With Guard Clauses)
In your drop handler, add checks to ensure data exists before parsing it to avoid the JSON error:
const handleDrop = (e) => { e.preventDefault(); // Critical to override default browser drop behavior const nativeDropEvent = e.nativeEvent; // Check if the data type exists before trying to retrieve it if (nativeDropEvent.dataTransfer.types.includes("text/plain")) { const payloadStr = nativeDropEvent.dataTransfer.getData("text/plain"); // Guard against empty strings before parsing if (payloadStr) { try { const payload = JSON.parse(payloadStr); // Do something with your parsed data here console.log("Dropped item:", payload); } catch (parseErr) { console.error("Failed to parse dragged data:", parseErr); } } } };
4. Don't Forget onDragOver
You need to prevent the default behavior in onDragOver to let the drop event fire in IE/Edge:
const handleDragOver = (e) => { e.preventDefault(); };
Full Component Example
Putting it all together in a working component:
import React from "react"; const DragDropComponent = () => { const handleDragStart = (e) => { const nativeDragEvent = e.nativeEvent; const payload = JSON.stringify({ itemId: 123, content: "Drag me!" }); nativeDragEvent.dataTransfer.setData("text/plain", payload); nativeDragEvent.dataTransfer.effectAllowed = "move"; }; const handleDragOver = (e) => { e.preventDefault(); }; const handleDrop = (e) => { e.preventDefault(); const nativeDropEvent = e.nativeEvent; if (nativeDropEvent.dataTransfer.types.includes("text/plain")) { const payloadStr = nativeDropEvent.dataTransfer.getData("text/plain"); if (payloadStr) { try { const payload = JSON.parse(payloadStr); alert(`You dropped item #${payload.itemId}: ${payload.content}`); } catch (err) { console.error("Parse error:", err); } } } }; return ( <div> <div draggable onDragStart={handleDragStart} style={{ padding: "1rem", border: "1px solid #ccc", margin: "1rem" }} > Drag This Box </div> <div onDrop={handleDrop} onDragOver={handleDragOver} style={{ padding: "2rem", border: "2px dashed #ccc", margin: "1rem" }} > Drop Here </div> </div> ); }; export default DragDropComponent;
Key Takeaways
- IE/Edge have non-negotiable timing rules for
dataTransfer—stick tosetDataindragstartandgetDataindrop. - Always use the native event instead of React's synthetic event for
dataTransferoperations. - Guard against empty strings before parsing to avoid JSON errors.
内容的提问来源于stack exchange,提问作者Ben Clarke

