1. 16:41 09/10/2026
**Giới thiệu**
Tích hợp tính năng upload file vào ứng dụng web hoặc di động ngày nay là điều gần như bắt buộc, dù bạn đang xây dựng một công cụ cộng tác dựa trên cloud hay một ứng dụng ghi chú đơn giản. Người dùng mong đợi một quy trình upload file trực quan, phản hồi nhanh chóng và đáng tin cậy—có thể xử lý các tệp nhỏ một cách nhanh chóng cũng như truyền tải các tệp lớn một cách ổn định.
**Những thách thức chính**
1. **Kích thước tệp** – Trình duyệt giới hạn kích thước upload tổng thể; các tệp lớn hơn đòi hỏi phải chia nhỏ.
2. **Kiểm tra tính hợp lệ** – Cần xác minh định dạng, kích thước và nội dung để đảm bảo an toàn.
3. **Trạng thái upload** – Người dùng cần biết tiến trình upload đang diễn ra, đặc biệt khi truyền tải các tệp lớn.
4. **Tích hợp server** – Giao tiếp bất đồng bộ với API phải đơn giản và có khả năng phục hồi.
**Các bước triển khai**
*1. Thiết lập component upload cơ bản*
Render một vùng drag‑and‑drop và một input file ẩn. Bắt sự kiện `onDrop` để đọc các tệp đã chọn và lưu vào state.
```text
function FileUpload({ onFilesSelected }) {
const handleDrop = (e) => {
e.preventDefault();
const files = Array.from(e.dataTransfer.files);
onFilesSelected(files);
};
return (
<div
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
style={{ border: '2px dashed #aaa', padding: '2rem', textAlign: 'center', cursor: 'pointer' }}
>
Kéo và thả tệp vào đây hoặc nhấp để chọn
</div>
);
}
```
*2. Xác thực tệp ngay lập tức*
Trước khi upload, hãy kiểm tra phần mở rộng, loại MIME và kích thước. Hiển thị các thông báo lỗi rõ ràng.
```text
const validateFile = (file) => {
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
const maxSize = 10 * 1024 * 1024; // 10 MB
if (!allowedTypes.includes(file.type)) {
throw new Error('Loại tệp không được hỗ trợ');
}
if (file.size > maxSize) {
throw new Error('Tệp vượt quá giới hạn 10 MB');
}
return true;
};
```
*3. Theo dõi tiến trình upload*
Sử dụng API `FormData` cùng với `XMLHttpRequest` (hoặc `fetch` với `progress` event) để cập nhật thanh tiến trình. Đối với các tệp lớn, hãy chia nhỏ thành các chunk có kích thước 5 MB.
```text
function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
// cập nhật UI thanh tiến trình
}
});
xhr.open('POST', '/api/upload');
xhr.onload = () => xhr.status === 200 ? resolve(xhr.response) : reject(xhr.statusText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send(formData);
});
}
```
*4. Tích hợp server*
Tạo một endpoint đơn giản để nhận tệp (hoặc các chunk) và lưu trữ chúng vào dịch vụ lưu trữ cloud (ví dụ: AWS S3, Cloudinary). Trả về một ID tệp để tham chiếu sau này.
**Lời khuyên thực tế**
- **Luôn sử dụng tên tệp an toàn** trên server để tránh xung đột và tấn công path traversal.
- **Hiển thị thông báo thành công/thất bại rõ ràng** cho người dùng.
- **Cho phép hủy upload** bằng cách lưu trữ đối tượng `XMLHttpRequest` và gọi `abort()`.
- **Lưu vào cache các tệp đã upload gần đây** để người dùng có thể retry nhanh chóng mà không cần tải lại.
- **Tận dụng các thư viện hiện có** (ví dụ: `react-dropzone`, `react-native-document-picker`) để tiết kiệm thời gian và đảm bảo tính nhất quán trên các nền tảng.
**Kết luận**
Một quy trình upload file mạnh mẽ không chỉ là việc xử lý các yêu cầu HTTP; đó là sự kết hợp giữa giao diện người dùng trực quan, xác thực chặt chẽ, theo dõi tiến trình minh bạch và tích hợp server đáng tin cậy. Bằng cách làm theo các bước trên, bạn có thể tạo ra một quy trình upload file hoạt động tốt trên cả React web và React Native, mang lại trải nghiệm chuyên nghiệp cho người dùng cuối.