Codementor Events

How to parse file names when dropping a folder on customized dropzone in React

Published Jun 07, 2020

Alright we are not talking about dropping ourselves from the sky. We are talking about…
Dropzone!
Before diving into this article, I would assume whoever is reading this knows a good amount of react and javascript.
If you are dealing with drag and dropping files and folders, most likely you have used react-dropzone. But what if you want to customize your dropzone?
In my customized version of dropzone it consists of three components:
DropTarget.js
DropList.js
dropEffects.js
What are all these files?
DropTarget is the file that actually does all the handling of figuring what files are in a folder,etc. Here is the implementation for DropTarget.js:
import React from "react";
import PropTypes from "prop-types";
import * as dropEffects from "./dropEffects";
const insideStyle = {
backgroundColor: "#cccccc",
opacity: 0.5,
};
const DropTarget = (props) => {
const [isOver, setIsOver] = React.useState(false);

const dragOver = (ev) => {
ev.preventDefault();
ev.dataTransfer.dropEffect = props.dropEffect;
};
const handleFiles = (file) => {
console.log(file);
};
const drop = (ev) => {
const droppedItem = ev.dataTransfer.getData("drag-item");
var entry = ev.dataTransfer.items[0].webkitGetAsEntry();

if (entry.isFile) {
entry.file(handleFiles);
} else if (entry.isDirectory) {
var reader = entry.createReader();
reader.readEntries(function (entries) {
entries.forEach(function (dir, key) {
dir.file(handleFiles);
});
});
}

setIsOver(false);
};
const dragEnter = (ev) => {
ev.dataTransfer.dropEffect = props.dropEffect;
setIsOver(true);
};
const dragLeave = () => setIsOver(false);
return (
<div
onDragOver={dragOver}
onDrop={drop}
onDragEnter={dragEnter}
onDragLeave={dragLeave}
style={{ width: "100%", height: "100%", ...(isOver ? insideStyle : {}) }}
>
Drop here!
</div>
);
};

DropTarget.propTypes = {
onItemDropped: PropTypes.func.isRequired,
dropEffect: PropTypes.string,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
};
DropTarget.defaultProps = {
dropEffect: dropEffects.All,
};
export default DropTarget;
There is a good amount of stuff going on so let’s only focus on few details. DropTarget returns a div that handles all kind of drag and drop features(onDrop, onDropOver, etc). In this scenario, the only one we really are concerned about is onDrop.
When the user drops a folder fulls of files onto the div, it is recognized as an event. Inside this event(know as ev in this example) within the drop function we get the item that is dragged. Assuming we are only dealing with one folder, we reference “ev.dataTransfer.items[0].webkitGetAsEntry()” which takes the first item that is dragged.
Afterward, we check if the entry.isFile() vs entry.isDirectory(). if it is a directory then we create a reader to parse the rest of the entries in that directory.
Here are two other files that are needed to make this work:
//DropList.js
import React from "react";
import DropTarget from "./DropTarget";
export default () => {
const [items, setItems] = React.useState([]);
const itemDropped = (item) => setItems([...items, item]);
console.log("drop list");
console.log("items: ", items);
return (
<DropTarget onItemDropped={itemDropped} dropEffect="link">
<div className="drag-drop-container">
{items.map((item) => {
return (
<div key={item} className="item">
{item}
</div>
);
})}
</div>
</DropTarget>
);
};
And another file that is referenced by DropTarget.js:
//dropEffects.js
export const All = "all";
export const Move = "move";
export const Copy = "copy";
export const Link = "link";
export const CopyOrMove = "copyMove";
export const CopyOrLink = "copyLink";
export const LinkOrMove = "linkMove";
export const None = "none";
Once you included all these three files in the folder, you can simply reference droplist just like this:
import React, { Component } from "react";
import DropList from "./components/DropList";
import logo from "./logo.svg";
import "./App.css";
class App extends Component {
render() {
return (
<div className="App">
<DropList />
</div>
);
}
}
export default App;
And there you have it!

Discover and read more posts from Michael Tong
get started
post commentsBe the first to share your opinion
Show more replies