Introduction
In this lab, we will learn how to create a file drag and drop component in React using the useState and useEffect hooks. This component allows users to easily drag and drop files onto a designated area and triggers a callback function with the dropped file as an argument. By the end of this lab, you will have a better understanding of how to handle drag and drop functionality in React.
File Drag and Drop Area
index.htmlandscript.jshave already been provided in the VM. In general, you only need to add code toscript.jsandstyle.css.
This component allows for drag and drop functionality for a single file. To implement this component, follow these steps:
- Create a reference called
dropRefand bind it to the component's wrapper. - Use the
useState()hook to create thedragandfilenamevariables. Initialize them tofalseand''respectively. - The variables
dragCounteranddragare used to determine if a file is being dragged, whilefilenameis used to store the dropped file's name. - Create the
handleDrag,handleDragIn,handleDragOut, andhandleDropmethods to handle drag and drop functionality.handleDragprevents the browser from opening the dragged file,handleDragInandhandleDragOuthandle the dragged file entering and exiting the component, andhandleDrophandles the file being dropped and passes it toonDrop. - Use the
useEffect()hook to handle each of the drag and drop events using the previously created methods.
Here is the CSS for the component:
.filedrop {
min-height: 120px;
border: 3px solid #d3d3d3;
text-align: center;
font-size: 24px;
padding: 32px;
border-radius: 4px;
}
.filedrop.drag {
border: 3px dashed #1e90ff;
}
.filedrop.ready {
border: 3px solid #32cd32;
}
Here is the JSX for the component:
const FileDrop = ({ onDrop }) => {
const [drag, setDrag] = React.useState(false);
const [filename, setFilename] = React.useState("");
const dropRef = React.useRef(null);
let dragCounter = 0;
const handleDrag = (e) => {
e.preventDefault();
e.stopPropagation();
};
const handleDragIn = (e) => {
e.preventDefault();
e.stopPropagation();
dragCounter++;
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);
};
const handleDragOut = (e) => {
e.preventDefault();
e.stopPropagation();
dragCounter--;
if (dragCounter === 0) setDrag(false);
};
const handleDrop = (e) => {
e.preventDefault();
e.stopPropagation();
setDrag(false);
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
onDrop(e.dataTransfer.files[0]);
setFilename(e.dataTransfer.files[0].name);
e.dataTransfer.clearData();
dragCounter = 0;
}
};
React.useEffect(() => {
const div = dropRef.current;
div.addEventListener("dragenter", handleDragIn);
div.addEventListener("dragleave", handleDragOut);
div.addEventListener("dragover", handleDrag);
div.addEventListener("drop", handleDrop);
return () => {
div.removeEventListener("dragenter", handleDragIn);
div.removeEventListener("dragleave", handleDragOut);
div.removeEventListener("dragover", handleDrag);
div.removeEventListener("drop", handleDrop);
};
}, []);
return (
<div
ref={dropRef}
className={
drag ? "filedrop drag" : filename ? "filedrop ready" : "filedrop"
}
>
{filename && !drag ? <div>{filename}</div> : <div>Drop a file here!</div>}
</div>
);
};
To use the component, call ReactDOM.createRoot(document.getElementById('root')).render(<FileDrop />);
Please click on 'Go Live' in the bottom right corner to run the web service on port 8080. Then, you can refresh the Web 8080 Tab to preview the web page.
Summary
Congratulations! You have completed the File Drag and Drop Area lab. You can practice more labs in LabEx to improve your skills.