Reusable React Code Modules, Part 12 - File Upload and Download
Efficient File Management: Building Reusable Modules for File Uploads and Downloads
File upload and download functionality is essential for many web applications, enabling users to interact with files in a seamless manner. This guide covers how to structure reusable file upload and download modules in React, manage files efficiently, and integrate common libraries. We will explore common libraries, compare their features, and provide practical examples and code snippets.
Common Libraries and Tools
1. React Dropzone
React Dropzone is a simple React component for handling file drops, widely used for file upload functionality
Key Features
Drag-and-drop support
Multiple file upload
File type and size validation
Customizable UI
2. FilePond
FilePond is a flexible and fun file upload library that works with React, providing a rich user experience
Key Features
Drag-and-drop interface
Async file upload
Image preview and editing
Plugin support
3. Axios
Axios is a promise-based HTTP client for JavaScript, commonly used for making HTTP requests, including file uploads and downloads
Key Features
Supports POST requests for file uploads
Configurable timeout and headers
Interceptors for request and response handling
Supports progress tracking
Comparison
React Dropzone: Best for simple drag-and-drop file upload interfaces with built-in validation
FilePond: Ideal for applications requiring a rich user interface and advanced features like image editing
Axios: Suitable for handling file uploads and downloads with HTTP requests, offering extensive customization
Examples
Example 1: React Dropzone
Setup:
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
const Dropzone = ({ onDrop }) => {
const onDropCallback = useCallback((acceptedFiles) => {
onDrop(acceptedFiles);
}, [onDrop]);
const { getRootProps, getInputProps } = useDropzone({ onDrop: onDropCallback });
return (
<div {...getRootProps()} style={{ border: '2px dashed #007bff', padding: '20px', textAlign: 'center' }}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
);
};
export default Dropzone;
Usage:
import React, { useState } from 'react';
import Dropzone from './Dropzone';
const FileUpload = () => {
const [files, setFiles] = useState([]);
const handleDrop = (acceptedFiles) => {
setFiles(acceptedFiles);
};
return (
<div>
<Dropzone onDrop={handleDrop} />
<ul>
{files.map((file) => (
<li key={file.path}>{file.path}</li>
))}
</ul>
</div>
);
};
export default FileUpload;
Example 2: FilePond
Setup:
import React from 'react';
import { FilePond, registerPlugin } from 'react-filepond';
import 'filepond/dist/filepond.min.css';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
registerPlugin(FilePondPluginImagePreview);
const FilePondComponent = ({ server }) => (
<FilePond
server={server}
allowMultiple={true}
name="files"
labelIdle='Drag & Drop your files or <span class="filepond--label-action">Browse</span>'
/>
);
export default FilePondComponent;
Usage:
import React from 'react';
import FilePondComponent from './FilePondComponent';
const FileUpload = () => {
return (
<div>
<h1>File Upload with FilePond</h1>
<FilePondComponent server="/api/upload" />
</div>
);
};
export default FileUpload;
Example 3: Axios for File Upload
Setup:
import axios from 'axios';
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`File upload progress: ${percentCompleted}%`);
},
});
return response.data;
};
export default uploadFile;
Usage:
import React, { useState } from 'react';
import uploadFile from './uploadFile';
const FileUpload = () => {
const [file, setFile] = useState(null);
const handleFileChange = (event) => {
setFile(event.target.files[0]);
};
const handleUpload = async () => {
if (file) {
const response = await uploadFile(file);
console.log('File uploaded:', response);
}
};
return (
<div>
<h1>File Upload with Axios</h1>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>Upload</button>
</div>
);
};
export default FileUpload;