Skip to content

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 回调监控进度
  • 注意处理上传失败的情况

使用注意事项 ​

  1. 文件类型限制
  • 通过 input 的 accept 属性限制可上传的文件类型
  • 在代码中也要进行文件类型的验证
  1. 文件大小限制
  • 建议在上传前检查文件大小
  • 可以设置最大文件数量限制
  1. 性能优化
  • 大文件上传考虑分片上传
  • 图片预览时注意压缩处理
  1. 用户体验
  • 添加适当的loading状态
  • 提供清晰的错误提示
  • 支持取消上传操作