简介
在本实验中,我们将学习如何使用 useState 和 useEffect 钩子在 React 中创建一个文件拖放组件。该组件允许用户轻松地将文件拖放到指定区域,并触发一个回调函数,将拖放的文件作为参数传递。完成本实验后,你将更好地理解如何在 React 中处理拖放功能。
在本实验中,我们将学习如何使用 useState 和 useEffect 钩子在 React 中创建一个文件拖放组件。该组件允许用户轻松地将文件拖放到指定区域,并触发一个回调函数,将拖放的文件作为参数传递。完成本实验后,你将更好地理解如何在 React 中处理拖放功能。
虚拟机中已经提供了
index.html和script.js。一般来说,你只需要在script.js和style.css中添加代码。
此组件允许对单个文件进行拖放功能。要实现此组件,请执行以下步骤:
dropRef 的引用,并将其绑定到组件的包装器。useState() 钩子创建 drag 和 filename 变量。分别将它们初始化为 false 和 ''。dragCounter 和 drag 用于确定文件是否正在被拖动,而 filename 用于存储拖放文件的名称。handleDrag、handleDragIn、handleDragOut 和 handleDrop 方法来处理拖放功能。handleDrag 防止浏览器打开被拖动的文件,handleDragIn 和 handleDragOut 处理被拖动的文件进入和离开组件,handleDrop 处理文件被放下并将其传递给 onDrop。useEffect() 钩子,使用先前创建的方法处理每个拖放事件。以下是该组件的 CSS:
.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;
}
以下是该组件的 JSX:
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>
);
};
要使用该组件,请调用 ReactDOM.createRoot(document.getElementById('root')).render(<FileDrop onDrop={console.log} />);
请点击右下角的“Go Live”以在端口 8080 上运行 Web 服务。然后,你可以刷新“Web 8080”标签页来预览网页。
恭喜你!你已经完成了文件拖放区域实验。你可以在 LabEx 中练习更多实验来提升你的技能。