1. 18:02 09/10/2026
**Giới thiệu**
Quy trình upload file là một trong những tính năng phổ biến trong hầu hết các ứng dụng web và di động hiện đại. Dù bạn đang xây dựng một công cụ chia sẻ tài liệu dựa trên React, một ứng dụng di động React Native hay một portal quản lý nội dung đa nền tảng, việc thiết kế một quy trình upload file đáng tin cậy, thân thiện người dùng và dễ bảo trì là điều vô cùng quan trọng.
**Thách thức chính**
1. **Hạn chế về mặt client** – kích thước tệp, loại tệp, giới hạn tốc độ.
2. **Kiểm soát từ server** – xác thực tệp, lưu trữ, xử lý sau upload.
3. **Trải nghiệm người dùng** – phản hồi trực quan về tiến trình, thông báo lỗi rõ ràng, khả năng hủy/thử lại.
4. **Hiệu suất** – xử lý đồng thời nhiều tệp, upload song song, sử dụng bộ nhớ tối ưu.
**Các mẫu thiết kế thực tế**
### 1. Validation phân cấp
- **Kiểm tra trước khi upload** (kích thước, loại MIME, phần mở rộng) ngay lập tức giúp người dùng không phải chờ request.
- **Xác thực từ server** (ví dụ: kiểm tra tính toàn vẹn, phát hiện virus) để đảm bảo tính bảo mật.
```js
// Ví dụ: hook validation từ client
const validateFile = (file) => {
const maxSize = 10 * 1024 * 1024; // 10 MB
const allowedTypes = ['image/jpeg','application/pdf'];
if (file.size > maxSize) throw new Error('File vượt quá 10 MB');
if (!allowedTypes.includes(file.type)) throw new Error('Loại tệp không được hỗ trợ');
return true;
};
```
### 2. Theo dõi tiến trình upload
- Sử dụng `FormData` cùng `XMLHttpRequest` (hoặc `fetch` với `progress`) để hiển thị thanh tiến trình.
- Lưu trạng thái vào `localStorage` hoặc một cửa hàng đơn giản (Redux, Zustand) để khôi phục sau khi làm mới.
```js
const uploadWithProgress = (file, onProgress) => {
const formData = new FormData();
formData.append('file', file);
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
onProgress(Math.round((e.loaded / e.total) * 100));
}
});
// ... gửi request
};
```
### 3. Tích hợp server
- **REST/GraphQL** – trả về URL hoặc ID tệp để tham chiếu sau này.
- **WebSocket hoặc server‑sent events** – cập nhật thời gian thực về trạng thái xử lý.
- **Xử lý sau upload** – chuyển đổi, lưu vào cơ sở dữ liệu, tạo bản xem trước.
### 4. Xử lý nhiều loại tệp và upload song song
- Phân loại tệp theo loại (hình ảnh, video, tài liệu).
- Upload nhiều tệp cùng lúc bằng `Promise.all` nhưng giới hạn số lượng request đang chờ xử lý để tránh quá tải.
```js
const uploadBatch = async (files, maxConcurrent = 3) => {
const queue = [...files];
const results = [];
while (queue.length) {
const batch = queue.splice(0, maxConcurrent);
const batchResults = await Promise.all(
batch.map(file => uploadWithProgress(file))
);
results.push(...batchResults);
}
return results;
};
```
**Lời khuyên thực tế**
- **Tận dụng custom hooks** (ví dụ: `useFileUpload`) để tái sử dụng logic validation, tiến trình và lỗi giữa React và React Native.
- **Sử dụng Context/API chung** cho các endpoint server để tránh code duplication.
- **Kiểm tra nghiêm ngặt** trên cả hai nền tảng: sử dụng `jsdom` cho React web và `react-native` testing library cho React Native.
- **Tối ưu hóa hiệu suất** bằng cách sử dụng `Compression` cho các tệp lớn và cache phản hồi từ server để giảm request thừa.
**Kết luận**
Bằng cách kết hợp validation từ client và server, phản hồi trực quan về tiến trình mượt mà và một hệ thống upload linh hoạt, bạn có thể xây dựng một quy trình upload file hoạt động tốt trên React, React Native và mở rộng dễ dàng khi ứng dụng phát triển.