react hook + antd upload 通過fileList控制文件列表展示status為uploading


項目是用的react hook寫的,引入了antd 的upload上傳組件,頁面效果如下

代碼

import React, { useState } from 'react'
import { Modal, Form, Upload, message, Button } from 'antd'
import { UploadOutlined } from '@ant-design/icons'
import { TableListItem } from '@/services/data.d'
import { importByExcelUrl } from '@/services/manually'
import { validFileSize } from '@/utils/validate'

export interface FormValueType extends Partial<TableListItem> {
  time?: string;
  [propName: string]: any
}

const FormItem = Form.Item

interface CreateFormProps {
  modalVisible: boolean;
  onCancel: () => void;
  onConfirm: (values: FormValueType) => void;
  values: any
}
const formLayout = {
  labelCol: { span: 7 },
  wrapperCol: { span: 13 },
}

const UploadForm: React.FC<CreateFormProps> = (props) => {
  const { modalVisible, onConfirm, onCancel } = props
  const [bussinessFileList, setFilelist] = useState<any[]>([])
  const [uploadFileList, setUploadFilelist] = useState<any[]>([])
  const [form] = Form.useForm()

  form.setFieldsValue({})

  const uploadprops = {
    name: 'file',
    action: importByExcelUrl(),
    headers: {
      authorization: 'authorization-text',
    },
    accept:
      '.csv,.xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel',
    data: { businessCode: props.values },
    disabled: bussinessFileList.length === 1,
    fileList: uploadFileList,
    beforeUpload(file: any) {
      // console.log(6, file, uploadFileList.length, validFileSize(file))
      if (uploadFileList.length > 0) {
        message.warning('只能上傳一個文件')
        return false
      }
      if (file.size === 0) {
        message.error('文件不能為空')
        return false
      }
      return validFileSize(file)
    },
    onChange(info: any) {
      let files: any[] = [...info.fileList]
      if (info.file.status === 'done') {
        if (info.file.response) {
          if (info.file.response.responseCode === '000000') {
            // files = [...info.fileList]
            message.success(`${info.file.name} 文件上傳成功`)
          } else {
            message.error(info.file.response.responseMsg)
          }
        } else {
          message.error(`${info.file.name} 上傳失敗.`)
        }
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上傳失敗.`)
      }
      files = files.filter((item : any) => {
        return item.response?.responseCode === '000000'
      })
      files = JSON.parse(JSON.stringify(files))
      console.log(66666, info, files)
      setUploadFilelist(files)
      setFilelist(files)
    },
  }

  const renderContent = () => {
    return (
      <>
        <FormItem
          name='uploads'
          label='上傳模板'
          required
          rules={[{ validator: (rule, value, callback) => {
            if (value && value.fileList && value.fileList.length) {
              console.log(77, value)
              if (value.file.response && value.file.response.responseCode === '000000') {
                callback()
              } else if (value.file.status && value.file.status === 'uploading') {
                callback()
              } else {
                callback('文件信息有誤,請刪除后上傳正確文件')
              }
            } else callback('請選擇文件上傳')
          } }]}
        >
          <Upload {...uploadprops}>
            <Button>
              <UploadOutlined /> 點擊上傳
            </Button>
          </Upload>
        </FormItem>
      </>
    )
  }
  const handleConfirm = async() => {
    const fieldsValue = await form.validateFields()
    // console.log(fieldsValue)
    onConfirm(fieldsValue)
  }

  return (
    <Modal
      destroyOnClose
      title='上傳模板'
      visible={modalVisible}
      onOk={() => handleConfirm()}
      maskClosable={false}
      onCancel={() => onCancel()}
    >
      <Form
        {...formLayout}
        form={form}
        initialValues={{}}
      >
        {renderContent()}
      </Form>
    </Modal>
  )
}

export default UploadForm

想做到的效果是用戶文件上傳正確,才展示在頁面上,上傳錯誤不展示在頁面上.使用了upload的fileList屬性,發現文件上傳狀態一直是uploading

 

在官網找了一圈答案https://github.com/ant-design/ant-design/issues/2423這個issue里有問題描述,試了里面的一些方法還是不起作用

后面發現實際問題是,fileList這個屬性不能設置為空數組

這里已經說得很明白了,所以說想用這個屬性來控制文件,就必須保證不會為空數組,但是這個跟我的需求不符,所以后來沒用這個屬性,是用form的rules來提示客戶刪除不正確的文件重新上傳

但是如果一定要實現這個功能可以自己寫fileList

 <FormItem
          name='uploads'
          label='上傳模板'
          required
          rules={[{ validator: (rule, value, callback) => {
            if (value && value.fileList && value.fileList.length) {
              console.log(77, value)
              if (value.file.response && value.file.response.responseCode === '000000') {
                callback()
              } else if (value.file.status && value.file.status === 'uploading') {
                callback()
              } else {
                callback('文件信息有誤,請刪除后上傳正確文件')
              }
            } else callback('請選擇文件上傳')
          } }]}
        >
          <>
            <Upload {...uploadprops} showUploadList={false}>
              <Button>
                <UploadOutlined /> 點擊上傳
              </Button>
            </Upload>
            {bussinessFileList.length ? <ul>     // 大概的就是這樣,具體樣式自己要調整一下 {bussinessFileList.map(item => <li key={item.uid}> {item.name} </li>)}
            </ul> : null}
          </>
        </FormItem>

這樣寫要注意一個問題,formtien默認值會獲取內部的一個閉合標簽的值,這里加了列表之后,form rules里面的value將會獲取不到file上傳的內容,可以換成bussinessFileList判斷

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM