React ant Upload上传组件,使用hooks技术上传图片遇到的问题及解决方案

问题:文件上传失败时不需要回显。

思路:添加fileList属性,绑定一个列表,上传成功的文件才加入列表中,代码如下:


const [ imgFileList, setImgFileList ] = useState<any[]>([]);

 
<Upload
	name='upload_file'
    action="/file/upload/v4" //这个路径是我项目中封装好的路径接口,根据自己的项目接口替换
    accept='image/jpeg,image/jpg,image/png'
    fileList={imgFileList}
    onChange={resp => {
        const _file = resp.file || {};
        if(_file.status!=="done") return
        // 上传成功
        if (_file.response?.status == 0) {
            const uid = _file.response?.uid || "";
            handleFileListChange([uid]);
        }else{
            notification["error"]({
                message: _file.response?.msg||"上传文件失败,请重新上传"
            });
        }
    }}
>

代码这样写看似没有问题,但实际上执行onChange回调方法的时候,却只执行到了uploading状态,没有接着往下走done状态,这就出现了很大的问题。解决方式如下所示:

...  
const [ imgFileList, setImgFileList ] = useState<any[]>([]);
...
 
<Upload
    name='upload_file'
    action="/file/upload/v4"
    fileList={imgFileList}
    ...
    onChange={resp => {
        const _file:any = resp.file || {};
        if (_file.status == "uploading") {
            // 在这里设置一下需要展示的文件才会继续走到done状态
            setImgFileList([_file]);
            return;
        }else if (["removed","error"].indexOf(_file.status) !== -1) {
            // "removed","error"状态时也设置一下
            setImgFileList([]);
            return;
        }
        
        // done状态
        // 后端返回状态码为0证明上传成功
        if (_file.response?.status == 0) {
            const uid = _file.response?.uid || "";
        } else {
            notification["error"]({
                message: _file.response?.msg || "上传文件失败,请重新上传"
            });
        }
    }}
>

uploading状态里设置下即可往下走done状态

不过这个写法对于我在项目中开发的内容还有些限制,我在开发中,按照上面的内容开发,确实能够上传,不过还是出现了其他问题,不能满足我项目的功能需求,个人建议还是使用我下面的方法比较妥当:

思路:
    1、对于upload组件使用showUploadList={false} 取消展示
    2、使用useState 定义一个存放上传图片的变量
    3、图片上传后,将图片地址存到该变量中
    4、自定义一个div,里面使用map遍历文件,用于展示图片

代码如下:

// 这是自定义的div
 const imgDiv = (
    <div style={{display: 'flex'}}>
      {imgFileList.map((item: any) => (
        <div style={{position: 'relative'}}>
          <div hidden={showDelIcon} className='del' onClick={() => handleDelImg(item)}>
            <span className='icon'>X</span>
            {/*<CloseCircleOutlined style={{color: '#fff'}} />*/}
          </div>
          <Image
          width={100}
          height={100}
          src={item.fileUrl} />
        </div>
      ))}
    </div>
  )
// upload上传组件
<div style={{display: 'flex'}}>
              {imgDiv}
              <Upload name='upload_file'
                      listType="picture-card"
                      showUploadList={false}
                      action='/file/upload/v4'
                      headers={{appCode: 'range-land-emp-happy'}}
                      maxCount={5} accept={'image/jpeg,image/jpg,image/png'}
                      beforeUpload={handleBeforeUpload}
                      onPreview={handlePreview}
                      onRemove={handleRemoveImg}
                      onChange={handleImgChange}>
                {isDisabled ? null : <div>
                  <PlusOutlined style={{ fontSize: '32px', color: '#D1D1D1' }}/>
                  <div style={{ marginTop: 10  }}></div>
                </div>}
              </Upload>
            </div>

  // 图片上传状态改变回调
  const handleImgChange = (info: any) => {
    if (info.file.status === 'uploading') {
      return;
    }
    // 图片上传成功,往里面追加一条记录
    if (info.file.status === 'done') {
      let ext:any = info.file.type.split('/')[1]
      const newData = { id: '', rowId: generateUUID(), fileTypeId: '材料图片', fileType:'材料图片', fileName: info.file.name, fileUrl: info.file.response.data.rows[0].url, progress: info.file.percent, fileExt: ext, fileSize: info.file.size}
      const { response, response: {status}} = info.file
      if (status === 200 && response.data.rows[0]) {
        message.success('上传成功')
        setImgFileList(() => {
          return [...imgFileList, newData]
        })
      } else {
        message.error(response.message || '上传失败')
      }
    }
  }

// 图片上传之前回调
const handleBeforeUpload = (file:any) => {
  // 判断上传的是否是图片
  if (!judgeImg(file.name)) {
    message.warning('请上传图片格式的文件')
    return Upload.LIST_IGNORE
  }
  if (imgFileList.length>=5) {
    message.warning('最多上传5张图片')
    return Upload.LIST_IGNORE
  }
}

按照这个流程上传完全没问题!!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值