Handling file uploads in a React app is straightforward, but things get more interesting when you need to filter for specific file types and parse their contents. I needed to create an upload button that only accepted JSON and YAML files, then read and displayed their contents in the browser. Here’s how I did it.
Thank me by sharing on Twitter 🙏
Setting Up the File Input
The standard <input type="file">
element works well for uploads, but I wanted a clean, styled button instead of a visible file picker. The trick is to hide the input and use a <label>
styled as a button. That way, clicking the label triggers the file selection.
Here’s how I set it up:
<input
type="file"
accept=".json,.yaml,.yml"
onChange={handleFileUpload}
id="fileInput"
style={{ display: "none" }}
/>
<label
htmlFor="fileInput"
style={{
display: "inline-block",
padding: "10px 16px",
backgroundColor: "#007bff",
color: "#fff",
borderRadius: "5px",
cursor: "pointer",
fontSize: "16px",
textAlign: "center",
}}
>
Upload JSON or YAML
</label>
Now, when a user clicks the button, the file picker opens, but the input remains hidden.
Filtering for JSON and YAML Files
Not all uploaded files should be processed. To enforce this, I checked the file’s extension before reading it:
Excel Formulas QuickStudy Laminated Study Guide (QuickStudy Computer)
$5.53 (as of March 12, 2025 13:35 GMT +00:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Elon Musk
$22.96 (as of March 12, 2025 13:35 GMT +00:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Brother Genuine Standard Yield Toner Cartridge, TN730, Replacement Black Toner, Page Yield Up To 1,200 Pages, Amazon Dash Replenishment Cartridge,1 Pack
$47.98 (as of March 9, 2025 13:34 GMT +00:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)const handleFileUpload = (event) => {
const file = event.target.files[0];
if (!file) return;
const fileExtension = file.name.split(".").pop().toLowerCase();
if (!["json", "yaml", "yml"].includes(fileExtension)) {
setError("Invalid file type. Please upload a JSON or YAML file.");
return;
}
readFile(file, fileExtension);
};
This ensures that only JSON or YAML files are processed. If a user selects something else, they see an error message instead of unexpected behavior.
Reading and Parsing File Contents
Once a valid file is selected, it needs to be read and parsed. I used the FileReader
API to read the contents as text. Then, based on the file extension, I parsed it as either JSON or YAML.
import yaml from "js-yaml";
const readFile = (file, fileExtension) => {
const reader = new FileReader();
reader.onload = (e) => {
try {
const content = e.target.result;
let parsedData;
if (fileExtension === "json") {
parsedData = JSON.parse(content);
} else {
parsedData = yaml.load(content);
}
setParsedData(parsedData);
setError("");
} catch {
setError("Error parsing the file. Please check its format.");
}
};
reader.readAsText(file);
};
This approach ensures that JSON files are parsed with JSON.parse
, while YAML files use the js-yaml
library.
Displaying the Parsed Data
To make the parsed data easy to read, I formatted it with JSON.stringify
and displayed it inside a styled <pre>
element.
{parsedData && (
<div
style={{
marginTop: "20px",
padding: "10px",
backgroundColor: "#f4f4f4",
borderRadius: "5px",
whiteSpace: "pre-wrap",
wordWrap: "break-word",
fontFamily: "monospace",
}}
>
<strong>Parsed Data:</strong>
<pre>{JSON.stringify(parsedData, null, 2)}</pre>
</div>
)}
Now, when a user uploads a valid JSON or YAML file, its contents appear in a readable format on the page.
Wrapping It Up
With this setup, I now have a React component that allows users to upload JSON and YAML files, filters out invalid files, parses their contents, and displays the results. By using a hidden file input and a styled label, the UI remains clean and intuitive. Whether working with configuration files or structured data, this approach makes handling file uploads simple and effective.