How to Read a CSV File in React
Jasser Mark Arioste
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:
- The user selects the CSV file using an
<input type="file"/>
element - Read the file using the fetch API. The
FileReader
API is also an alternative, but I find using the fetch API much cleaner. - 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.
- 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:
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