How to Upload Files with Progress in React

Introduction

File uploads with progress feedback significantly improve user experience. This tutorial shows how to build a complete upload component in React.

Step 1: Create the Upload Component

function FileUpload() {
  const [progress, setProgress] = useState(0);
  const [dragging, setDragging] = useState(false);

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files[0];
    uploadFile(file);
  };

  return (
    <div onDrop={handleDrop} onDragOver={() => setDragging(true)}>
      <input type="file" onChange={(e) => uploadFile(e.target.files[0])} />
      <progress value={progress} max={100} />
    </div>
  );
}

Step 2: Track Upload Progress

const uploadFile = (file: File) => {
  const xhr = new XMLHttpRequest();
  xhr.upload.addEventListener("progress", (e) => {
    setProgress(Math.round((e.loaded / e.total) * 100));
  });
  const formData = new FormData();
  formData.append("file", file);
  xhr.open("POST", "/api/upload");
  xhr.send(formData);
};

Step 3: Validate Files

const validateFile = (file: File): string | null => {
  const allowed = ["image/png", "image/jpeg", "application/pdf"];
  if (!allowed.includes(file.type)) return "Unsupported file type";
  if (file.size > 10 * 1024 * 1024) return "File too large (max 10MB)";
  return null;
};

Conclusion

This component provides a complete file upload experience with drag-and-drop, progress tracking, and validation. You can extend it with chunked uploads for large files or concurrent uploads for multiple files.