react+antd+axios实现图片上传

1,666 阅读1分钟
import React from 'react'
import { Modal, Button, Upload, message } from 'antd'
import { UploadOutlined } from '@ant-design/icons';
import axios from 'axios'

export default class UploadSeatChat extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      fileList: [],
      uploading: false,
    }
  }

  beforeUpload = (file)=>{
    console.log('file.type', file)
     // 允许上传的格式
    let fileType = ['.png', '.jpg', '.jpeg', '.PNG', '.JPG', '.JPEG', '.pdf', '.PDF']
    let hasNeedFileType = fileType.filter(item => file.name.includes(item))
    if (!hasNeedFileType.length) {
      message.error('只能上传 JPG/PNG/PDF 文件!');
    }
    let isLt1M = file.size / 1024 / 1024 < 1;
    if (!isLt1M) {
      message.error('文件必须小于1M');
    }
    let eligibleImage = hasNeedFileType.length && isLt1M
    let newFileList  = eligibleImage ? [...this.state.fileList, file] : [...this.state.fileList]
    this.setState({
      fileList: newFileList
    })
    return false
  }

  handleUpload = async () => {
    const { fileList } = this.state;
    if(!fileList.length) return
    // 这里直接用file上传到s3,不需要用formData去转换,
    // 而且axios使用了formData,无法手动设置content-type,默认就是'multipart/form-data',手动设置后还会被覆盖
    this.setState({
      uploading: true,
    });
    let { data: {url: uploadUrl}} =  await xxx.getUploadSeatChatUrl() //获取S3地址
    let options = {
      headers: {
        'Content-Type': fileList[0].type
      }
    };
    console.log('fileList', fileList)
    console.log('options', options)
    new Promise(resove => {
      axios.put(uploadUrl, fileList[0], options);
      resove()
    }).then(()=>{
      message.success('座位表上传成功');
      this.handleClose()
      this.props.onConfirmUploadSeatChatModal()
    })
  }

  handleClose = () => {
    this.setState({
      fileList: [],
      uploading: false,
    })
  }

  handleCancel=()=>{
    this.handleClose()
    this.props.onCloseUploadSeatChatModal()
  }

  render() {
    const { uploading, fileList } = this.state
    const params = {
      onRemove: file => {
        this.setState(state => {
          const index = state.fileList.indexOf(file);
          const newFileList = state.fileList.slice();
          newFileList.splice(index, 1);
          return {
            fileList: newFileList,
            uploading: false,
          };
        });
      },
      fileList,
    };


    return (
      <Modal
        okText="确认"
        cancelText="取消"
        title="学生座位表上传"
        onOk={this.handleUpload}
        onCancel={this.handleCancel}
        okButtonProps={{ disabled: !fileList.length }}
        confirmLoading={uploading}
        width="620px"
      >
        <div>
          <Upload
            {...params}
            beforeUpload={this.beforeUpload}
          >
            <Button disabled={fileList.length>=1} ><UploadOutlined />上传座位表</Button>
          </Upload>
        </div>
      </Modal>
    )
  }
}