React实现文件上传组件
本文将介绍如何在React中实现一个功能完整的文件上传组件,包含以下特性:
- 点击上传
- 拖拽上传
- 多图片预览
- 上传进度条
- 图片删除功能
核心功能实现
1. 基础布局结构
组件主要包含三个状态的显示:
- 默认上传区域(可点击和拖拽)
- 图片预览区域(显示已选择的图片)
- 上传进度条
关键代码:
js
<div className={`uploadWrapper ${fileDropHover ? 'uploadHover' : ''}`}>
{isUploading ? (
// 上传进度条区域
<ProgressBar percentage={uploadPercentage} />
) : showImgBox ? (
// 图片预览区域
<PreviewArea images={images} onDelete={handleDelete} />
) : (
// 默认上传区域
<UploadArea onUpload={handleUploadIconClick} />
)}
</div>2. 点击上传实现
通过隐藏的 input 元素来实现:
js
const handleUploadIconClick = () => {
fileInputRef.current.click()
}
const handleFileInputChange = (e) => {
const fileList = [...e.target.files]
handleFiles(fileList)
}注意事项:
- 使用 ref 来控制隐藏的 input 元素
- 通过 accept 属性限制文件类型
- 记得处理多文件上传的情况
3. 拖拽上传实现
js
const handleFileDrop = (event) => {
event.preventDefault()
setIsDragging(false)
setFileDropHover(false)
const fileList = [...event.dataTransfer.files]
handleFiles(fileList)
}关键点:
- 需要阻止默认的拖拽行为
- 处理拖拽状态的样式变化
- 使用 dataTransfer.files 获取拖拽的文件
4. 图片预览功能
js
const handleFiles = (fileList) => {
const imageFiles = fileList.filter(file => file.type.startsWith('image/'))
Promise.all(imageFiles.map(file => new Promise((resolve) => {
const reader = new FileReader()
reader.onload = () => resolve({
fileName: file.name,
data: reader.result
})
reader.readAsDataURL(file)
}))).then((images) => {
setShowImgBox(true)
setImages(prev => [...prev, ...images])
})
}实现要点:
- 使用 FileReader 读取图片文件
- 转换为 base64 格式用于预览
- 使用 Promise.all 处理多图片并发读取
5. 上传进度监控
js
const handleUpload = async (images) => {
const formData = new FormData()
images.forEach(file => {
formData.append("file", file.data)
})
try {
await uploadRequest(formData, (progressEvent) => {
const percent = Math.floor((progressEvent.loaded * 100) / progressEvent.total)
setUploadPercentage(percent)
})
} catch (err) {
console.error('上传失败:', err)
}
}关键点:
- 使用 FormData 处理文件上传
- 通过 axios 的 onUploadProgress 回调监控进度
- 注意处理上传失败的情况
使用注意事项
- 文件类型限制
- 通过 input 的 accept 属性限制可上传的文件类型
- 在代码中也要进行文件类型的验证
- 文件大小限制
- 建议在上传前检查文件大小
- 可以设置最大文件数量限制
- 性能优化
- 大文件上传考虑分片上传
- 图片预览时注意压缩处理
- 用户体验
- 添加适当的loading状态
- 提供清晰的错误提示
- 支持取消上传操作