Câu hỏi thường gặp
Các câu hỏi và câu trả lời phổ biến về Dropup.
Tổng quan
Dropup là gì?
Dropup là một thư viện React nhẹ và headless để tải lên tệp. Nó cung cấp chức năng kéo-và-thả, xác thực tệp, theo dõi tiến trình tải lên và hỗ trợ lưu trữ đám mây - tất cả trong một gói dưới 10KB khi nén.
Tại sao "headless"?
Headless có nghĩa là Dropup không bao gồm bất kỳ thành phần UI nào. Nó cung cấp logic và quản lý trạng thái, trong khi bạn xây dựng giao diện theo cách bạn muốn. Điều này cho bạn toàn quyền kiểm soát giao diện.
Kích thước bundle là bao nhiêu?
- Core (
@samithahansaka/dropup): < 10KB khi nén - Với hỗ trợ đám mây: +2KB mỗi nhà cung cấp
- Với xử lý hình ảnh: +5KB
- Với giao thức tus: +3KB (yêu cầu tus-js-client)
Có hỗ trợ TypeScript không?
Có! Dropup được viết bằng TypeScript và bao gồm định nghĩa kiểu đầy đủ. Không cần gói @types.
Yêu cầu phiên bản React nào?
React 16.8+ (yêu cầu hỗ trợ hooks).
Sử dụng
Làm thế nào để tải lên tệp?
const { files, actions } = useDropup({
upload: { url: '/api/upload' },
});
// Tải lên tất cả tệp
actions.upload();
// Tải lên các tệp cụ thể
actions.upload(['file-id-1', 'file-id-2']);
Làm thế nào để xử lý lỗi xác thực?
useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
console.log(`${file.name}: ${errors.join(', ')}`);
});
},
});
Tôi có thể sử dụng logic tải lên tùy chỉnh không?
Có! Truyền một hàm thay vì đối tượng cấu hình:
useDropup({
upload: async (file, options) => {
const { signal, onProgress } = options;
// Logic tải lên tùy chỉnh của bạn
const response = await customUpload(file.file, {
signal,
onProgress,
});
return { url: response.url };
},
});
Làm thế nào để thêm tệp theo chương trình?
const { actions } = useDropup();
// Từ clipboard
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files) {
actions.addFiles(files);
}
});
Tôi có thể có nhiều vùng thả không?
Có! Mỗi lần gọi useDropup tạo ra một instance độc lập:
const images = useDropup({ accept: 'image/*' });
const documents = useDropup({ accept: '.pdf' });
// Sử dụng riêng biệt
<div {...images.getDropProps()}>...</div>
<div {...documents.getDropProps()}>...</div>
Tải lên
Làm thế nào để hiển thị tiến trình tải lên?
const { files } = useDropup({ upload: { url: '/api/upload' } });
{files.map(file => (
<div key={file.id}>
{file.name}: {file.progress}%
</div>
))}
Làm thế nào để hủy tải lên?
const { actions } = useDropup();
// Hủy tệp cụ thể
actions.cancel('file-id');
// Hủy tất cả tải lên
actions.cancel();
Làm thế nào để thử lại tải lên thất bại?
const { actions } = useDropup();
// Thử lại các tệp cụ thể
actions.retry(['file-id']);
// Thử lại tất cả thất bại
actions.retry();
Có hỗ trợ tải lên theo khối không?
Có! Sử dụng createChunkedUploader:
import { createChunkedUploader } from '@samithahansaka/dropup';
useDropup({
upload: createChunkedUploader({
url: '/api/upload/chunk',
chunkSize: 5 * 1024 * 1024, // 5MB
}),
});
Tôi có thể tải lên trực tiếp lên S3 không?
Có! Sử dụng cloud uploader:
import { createS3Uploader } from '@samithahansaka/dropup/cloud/s3';
useDropup({
upload: createS3Uploader({
getPresignedUrl: async (file) => {
const res = await fetch('/api/s3/presign', {
method: 'POST',
body: JSON.stringify({ filename: file.name }),
});
return res.json();
},
}),
});
Xác thực
Làm thế nào để giới hạn loại tệp?
// Theo loại MIME
useDropup({ accept: 'image/*' });
// Theo phần mở rộng
useDropup({ accept: '.pdf, .doc' });
// Nhiều loại
useDropup({ accept: ['image/*', 'application/pdf'] });
Làm thế nào để đặt giới hạn kích thước?
useDropup({
maxSize: 10 * 1024 * 1024, // Tối đa 10MB
minSize: 1024, // Tối thiểu 1KB
});
Làm thế nào để giới hạn số lượng tệp?
useDropup({
maxFiles: 5,
});
Tôi có thể thêm xác thực tùy chỉnh không?
Có! Sử dụng customRules:
useDropup({
customRules: [
(file) => {
if (file.name.includes('draft')) {
return 'Không cho phép tệp nháp';
}
return true;
},
],
});
Xem trước
Làm thế nào để hiển thị xem trước hình ảnh?
Xem trước được bật theo mặc định:
const { files } = useDropup();
{files.map(file => (
file.preview && <img src={file.preview} alt="" />
))}
Tôi có cần dọn dẹp URL xem trước không?
Không! Dropup tự động thu hồi Object URLs khi tệp bị xóa hoặc component unmount.
Tôi có thể tắt xem trước không?
useDropup({ generatePreviews: false });
Xử lý sự cố
Tệp không tải lên được
-
Kiểm tra xem
uploadđã được cấu hình chưa:useDropup({ upload: { url: '/api/upload' } }); -
Đảm bảo bạn gọi
actions.upload()(trừ khiautoUpload: true) -
Kiểm tra console trình duyệt để tìm lỗi mạng
URL xem trước không hoạt động
- Đảm bảo tệp là hình ảnh
- Kiểm tra xem
generatePreviewskhông phảifalse - Xác minh đối tượng file có thuộc tính
previewhợp lệ
Kéo và thả không hoạt động
- Đảm bảo bạn spread
getDropProps()trên phần tử container - Bao gồm input ẩn:
<input {...getInputProps()} /> - Kiểm tra xem
disabledkhông phảitrue
Lỗi TypeScript
- Cập nhật lên phiên bản Dropup mới nhất
- Đảm bảo
tsconfig.jsoncómoduleResolutionphù hợp - Kiểm tra xem
@samithahansaka/dropupnằm trongdependencies, không phảidevDependencies
Rò rỉ bộ nhớ
- Đảm bảo các component sử dụng
useDropupunmount đúng cách - Gọi
actions.reset()trước khi unmount nếu cần - Không lưu trữ tệp trong state bên ngoài mà không dọn dẹp
Tương thích
Có hoạt động với Next.js không?
Có! Sử dụng directive 'use client':
'use client';
import { useDropup } from '@samithahansaka/dropup';
Có hoạt động với React Native không?
Có! Sử dụng native adapter:
import { NativeAdapter } from '@samithahansaka/dropup/native';
useDropup({ adapter: NativeAdapter });
Có hỗ trợ SSR không?
Có! Dropup an toàn với SSR. Nó chỉ sử dụng các API trình duyệt khi chúng có sẵn.
Hỗ trợ trình duyệt?
Tất cả các trình duyệt hiện đại:
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
Đóng góp
Làm thế nào để đóng góp?
- Fork repository
- Tạo nhánh tính năng
- Gửi pull request
Xem CONTRIBUTING.md để biết chi tiết.
Làm thế nào để báo cáo lỗi?
Mở issue tại github.com/samithahansaka/dropup/issues.
Có lộ trình không?
Kiểm tra GitHub issues và discussions để biết các tính năng dự kiến.