How-to: A Simple Drag & Drop Files -Parsing CSVs

CSVs files are one of the most common files that we use all the time for exporting or importing data from external sources. So I guess, it is might be useful for us to know how to process them.

Let’s create a simple app demo on how to create a drop zone we can drag and drop files such as csv or images into our app and process it, either saving it to a form or uploading it to server.

Before we proceed though, it is worth checking out React-dropzone, which is a react hook that is designed to create a HTML-5 compliant drag and drop zone for files. You can check out the installation process and its usage.

But here, let’s create it from scratch. First, let’s create a simple create-react-app and also install react-papaparse.

npm install react-papaparse --save

react-papaparse is available on yarn as well. It can be installed with the following command:

yarn add react-papaparse

So initially, I have this on my screen. But for now, it does not do anything yet.

import React from "react";
import { parse } from "papaparse";
import "./App.css";

export default function App() {
	return (
		<div> 
			<h1 className="text-center text-4xl"> Import Contacts Here  </h1>
			<div className={`p-6 my-5 mx-auto max-w-md border-2`}>DROP YOUR CSV FILE HERE</div>
		</div>
);

}


I have also created a simple csv file for processing with two tables name and email.

Next, let’s build some event handlers that we need for droppable functionality. After creating the event handlers, we will need to handle or prevent first the default functionalities of the onDragOver and onDrop events.

If we try to drop a csv file into our dropzone, you will notice that the it will not do the default functionality of downloading our csv file.

But to check the file that we’ve just dropped, let’s put a console log on our onDrop event to see what information this event has.

onDragOver={(e) => {
          e.preventDefault();
        }}

onDrop={(e) => {
          e.preventDefault();
					console.log(e.dataTransfer.files) 

        }}

To process the file that has been dropped, let’s create an array that would us to loop over as well as filter files that we would be dragging into our drop zone. In this case, the file.type that we would be accepting is just a text/csv.

...

onDrop={(e) => {
          e.preventDefault();
					//console.log(e.dataTransfer.files) 
					Array.from(e.dataTransfer.files)
					.filter((file: any) => file.type === "text/csv")
				console.log(file) 

        }}

Console.log(file) first to check it its working.

Next, to access the file that has been dropped, let’s set up some some state and set it to initially to qan empty array.

const [contacts, setContacts] = useState([]);

And render it down in a list by mapping over the contacts.

			<ul>
        {contacts.map((contact) => (
          <li key={contact.email}>
            <strong>{contact.name}</strong>: {contact.email}
          </li>
        ))}
      </ul>

And render it down in a list by mapping over the contacts.

const [contacts, setContacts] = React.useState([
    { email: "[email protected]", name: "Jane Doe" },
  ]);

Once we know that it is working, we can begin to parse the contents in our droppable files. And would be import { parse } from “papaparse”;

...
import { parse } from "papaparse";

.....

Array.from(e.dataTransfer.files)

            .filter((file: any) => file.type === "text/csv") //you can validate or filter the type of file accepted
            .forEach(async (file) => {
              // @ts-ignore - File is from using Javascript type
              const text = await file.text();
              const result = parse(text, { header: true });
							//to append the results to our state
              setContacts((existing: any) => [...existing, ...result.data]);
            });
        }}
      >
        DROP YOUR CSV FILE HERE
      </div>

Then it is up to you to process your data, whether save it to send it to the server or whatever you need for your application.