ReactHustle

How to Read a CSV File in React

Jasser Mark Arioste

Jasser Mark Arioste

How to Read a CSV File in React

Hello, there! In this tutorial, you'll learn how to read CSV files in React, process the text and convert it into an array and display the data inside a table. We'll also explore how to use the papaparse library for parsing CSV files as it supports parsing large files.

How to Read a CSV File in React #

Below are the steps to read a CSV file in React:

  1. The user selects the CSV file using an <input type="file"/> element
  2. Read the file using the fetch API. The FileReader API is also an alternative, but I find using the fetch API much cleaner.
  3. Process the text per line to get the data. In this step, you can also process the data and convert it into javascript objects or JSON.
  4. Render the data to a table.

Step 1: Creating the <CSVSelector/> component #

The <CSVSelector/> component is a  component that allows the user to select a CSV file. It has an onChange event where it passes the processed data as a type string[][].

First, create the file components/CSVSelector.tsx and copy the code below:

// components/CSVSelector.tsx
import React from "react";

type Props = {
  onChange(data: string[][]): void;
};

const CSVSelector = ({ onChange }: Props) => {
  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      try {
        const file = e.target.files[0];

        // 1. create url from the file
        const fileUrl = URL.createObjectURL(file);

        // 2. use fetch API to read the file
        const response = await fetch(fileUrl);

        // 3. get the text from the response
        const text = await response.text();

        // 4. split the text by newline
        const lines = text.split("\n");

        // 5. map through all the lines and split each line by comma.
        const _data = lines.map((line) => line.split(","));

        // 6. call the onChange event
        onChange(_data);
      } catch (error) {
        console.error(error);
      }
    }
  };

  return <input type="file" accept=".csv" onChange={handleFileChange} />;
};

export default CSVSelector;
12345678910111213141516171819202122232425262728293031323334353637383940

The explanation is mentioned in the comments.

Step 2: Creating the <CSVReader/> component #

Next, let's create the <CSVReader/> component. The <CSVReader/> component watches any changes from the <CSVSelector/> component through the onChange callback function and displays the data in a table.

Create the file components/CSVReader.tsx and copy the code below.

// components/CSVReader
"use client";

import React, { useState } from "react";
import CSVSelector from "./CSVSelector";

const CSVReader = () => {
  const [data, setData] = useState<string[][]>([]);

  const headers = data[0];
  const rows = data.slice(1);
  return (
    <div>
      <CSVSelector onChange={(_data) => setData(_data)} />
      <table>
        <thead>
          <tr>
            {headers?.map((header, i) => (
              <th key={i}>{header}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows?.map((rowData, i) => {
            return (
              <tr key={i}>
                {rowData?.map((data, i) => {
                  return <td key={i}>{data}</td>;
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

export default CSVReader;
123456789101112131415161718192021222324252627282930313233343536373839

Explanation:

On lines 8 and 14, we represent the CSV data as a string[][] and we use the useState hook to store the data in memory when the onChange callback is called in the <CSVSelector/> component.

On lines 10 and 11, we separate the headers from the actual data.

Output #

Here's the output after those steps:

React Read CSV File

Parsing CSV for Production #

We've been able to parse CSV and display it in the browser but what if your CSV files have errors? Or the CSV file is huge? There are a lot of possible scenarios where errors occur and your current code won't be able to handle it.

In these situations, it's better to use a library that specializes in parsing CSV files and I recommend using the papaparse library. The papaparse library is a powerful CSV parse for the browser and it can handle pretty much 99% of scenarios when handling CSV files. 

To show you how it's done, let's refactor your CSVSelector.tsx file. But first, let's not forget to install papaparse library by running the command:

yarn add papaparse
# add types for typescript users
yarn add -D @types/papaparse 

Next, let's use papaparse when parsing the file.

// components/CSVSelector.tsx 
"use client";
import React from "react";
import Papa from "papaparse";
type Props = {
  onChange(data: string[][]): void;
};

const CSVSelector = ({ onChange }: Props) => {
  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      try {
        const file = e.target.files[0];

        Papa.parse<string[]>(file, {
          worker: true, // use a web worker so that the page doesn't hang up
          complete({ data }) {
            onChange(data);
          },
        });
        // 6. call the onChange event
      } catch (error) {
        console.error(error);
      }
    }
  };
  return <input type="file" accept=".csv" onChange={handleFileChange} />;
};

export default CSVSelector;
123456789101112131415161718192021222324252627282930

Full Code and Demo #

The full code can be accessed at GitHub: jmarioste/react-read-csv-file-tutorial.

You can play with the demo on Stackblitz: React Read Csv File Tutorial

Conclusion #

You learned how to read a CSV file in React and render the data in a table.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on GitHub.

Resources #

Credits: Image by Szabolcs Molnar from Pixabay

Share this post!

Related Posts

Disclaimer

This content may contain links to products, software and services. Please assume all such links are affiliate links which may result in my earning commissions and fees.
As an Amazon Associate, I earn from qualifying purchases. This means that whenever you buy a product on Amazon from a link on our site, we receive a small percentage of its price at no extra cost to you. This helps us continue to provide valuable content and reviews to you. Thank you for your support!
Donate to ReactHustle