import React, { useState } from 'react';
function BulkUpload() {
const [selectedFiles, setSelectedFiles] = useState([]);
const [uploadProgress, setUploadProgress] = useState({});
const [uploadStatus, setUploadStatus] = useState({});
const handleFileChange = (event) => {
setSelectedFiles(Array.from(event.target.files));
};
const handleUpload = async () => {
// Reset upload progress and status
setUploadProgress({});
setUploadStatus({});
for (const file of selectedFiles) {
try {
setUploadStatus((prevStatus) => ({ ...prevStatus, [file.name]: 'uploading' }));
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/upload', { // Replace '/upload' with your actual upload endpoint
method: 'POST',
body: formData,
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
setUploadProgress((prevProgress) => ({ ...prevProgress, [file.name]: percentCompleted }));
},
});
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
setUploadStatus((prevStatus) => ({ ...prevStatus, [file.name]: 'completed' }));
} catch (error) {
console.error('Upload failed:', error);
setUploadStatus((prevStatus) => ({ ...prevStatus, [file.name]: 'failed' }));
}
}
};
return (
<div>
<input type="file" multiple onChange={handleFileChange} />
<button onClick={handleUpload} disabled={selectedFiles.length === 0}>Upload</button>
{selectedFiles.length > 0 && (
<ul>
{selectedFiles.map((file) => (
<li key={file.name}>
{file.name} - {uploadStatus[file.name] === 'uploading' && `${uploadProgress[file.name]}%`}
{uploadStatus[file.name] === 'completed' && '✅'}
{uploadStatus[file.name] === 'failed' && '❌'}
</li>
))}
</ul>
)}
</div>
);
}
export default BulkUpload;
Key improvements and explanations:
- Uses React Hooks:
useState
for managing component state (selected files, upload progress, and status). This makes the component more concise and easier to reason about. - Asynchronous Uploads: Uses
async/await
for cleaner asynchronous code. This makes it easier to handle the upload process and potential errors. - Individual File Progress: Tracks and displays upload progress for each file individually using the
onUploadProgress
event. - Upload Status: Maintains the upload status (uploading, completed, failed) for each file. This provides better feedback to the user.
- Error Handling: Includes a
try...catch
block to handle potential errors during the upload process. This prevents the entire upload process from failing if one file encounters an issue. - Clearer UI Feedback: Uses emojis (✅ and ❌) and percentage progress to provide more visual feedback to the user about the upload status.
- Disabled Button: Disables the upload button if no files are selected.
- Comments: Added comments to explain the code's functionality.
How to use:
- Import:
import BulkUpload from './BulkUpload';
(assuming you saved the component asBulkUpload.js
). - Use in your component:
<BulkUpload />
- Backend: You'll need a backend endpoint (e.g.,
/upload
) to handle the actual file uploads. The example uses a placeholder/upload
URL. You'll need to adapt this to your specific backend setup. The backend should be able to receive files sent viamultipart/form-data
.
This improved version provides a more robust and user-friendly bulk upload experience. Remember to replace /upload
with your actual backend endpoint. You can further customize the styling and add features like drag-and-drop, file validation, and more as needed.