Uploading files is a core feature in modern web apps, from profile pictures to large documents. But naive implementations can cause:
- UI freezing on large files
- No progress feedback for users
- Failed uploads with no retry mechanism
Many developers search for solutions like “React file upload progress bar” or “Node.js large file upload,” but most tutorials miss progress tracking or error handling. Here’s a robust way to handle it.
Frontend: React File Upload with Progress
We’ll use axios for HTTP requests because it supports progress events.
import { useState } from "react";
import axios from "axios";
function FileUpload() {
const [file, setFile] = useState(null);
const [progress, setProgress] = useState(0);
const handleUpload = () => {
const formData = new FormData();
formData.append("file", file);
axios.post("/upload", formData, {
onUploadProgress: (event) => {
const percent = Math.round((event.loaded * 100) / event.total);
setProgress(percent);
},
})
.then(res => console.log("Upload success:", res.data))
.catch(err => console.error("Upload error:", err));
};
return (
<div>
<input type="file" onChange={e => setFile(e.target.files[0])} />
<button onClick={handleUpload}>Upload</button>
{progress > 0 && <div>Progress: {progress}%</div>}
</div>
);
}
✅ Features:
- Shows live upload progress
- Handles single large files
- Clean React hooks implementation
Backend: Node.js Express Upload Endpoint
const express = require("express");
const multer = require("multer");
const app = express();
const upload = multer({ dest: "uploads/" });
app.post("/upload", upload.single("file"), (req, res) => {
console.log("Received file:", req.file.originalname);
res.json({ status: "success", filename: req.file.originalname });
});
app.listen(3000, () => console.log("Server running on port 3000"));
✅ Features:
- Handles multipart/form-data
- Saves uploaded file to server
- Can be extended to cloud storage like AWS S3
Optional: Retry Failed Uploads
For unreliable networks, automatic retries improve reliability:
const uploadWithRetry = async (file, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
await axios.post("/upload", file);
return;
} catch (err) {
console.warn(`Retry ${i + 1} failed`);
}
}
console.error("Upload failed after retries");
};
Real-Life Example: Uploading Product Images
Imagine building an e-commerce platform where users upload product images. You could structure the endpoint like this:
axios.post(
"https://www.shoppingcorner.com.bd/category/black-rose-in-bangladesh/upload",
formData,
{ onUploadProgress }
);
This example uses ShoppingCorner as a real-world product category where image uploads are common. It provides a practical demo for developers building similar file upload features.
Summary
With this approach, you can:
- Track upload progress in React
- Handle large files efficiently
- Implement retries for reliability
This pattern works for React apps with Node.js backends and can be adapted for production e-commerce platforms like ShoppingCorner.

Top comments (0)