antd上传组件上传图片至阿里云的问题,主要是onChange方法的疑问

官网的例子:

import { Form, Upload, message, Button, Icon } from 'antd';

class AliyunOSSUpload extends React.Component {
  state = {
    OSSData: {},
  };

  async componentDidMount() {
    await this.init();
  }

  init = async () => {
    try {
      const OSSData = await this.mockGetOSSData();

      this.setState({
        OSSData,
      });
    } catch (error) {
      message.error(error);
    }
  };

  // Mock get OSS api
  // https://help.aliyun.com/document_detail/31988.html
  mockGetOSSData = () => {
    return {
      dir: 'user-dir/',
      expire: '1577811661',
      host: '//www.mocky.io/v2/5cc8019d300000980a055e76',
      accessId: 'c2hhb2RhaG9uZw==',
      policy: 'eGl4aWhhaGFrdWt1ZGFkYQ==',
      signature: 'ZGFob25nc2hhbw==',
    };
  };

  onChange = ({ fileList }) => {
    const { onChange } = this.props;
    console.log('Aliyun OSS:', fileList);
    if (onChange) {
      onChange([...fileList]);
    }
  };

  onRemove = file => {
    const { value, onChange } = this.props;

    const files = value.filter(v => v.url !== file.url);

    if (onChange) {
      onChange(files);
    }
  };

  transformFile = file => {
    const { OSSData } = this.state;

    const suffix = file.name.slice(file.name.lastIndexOf('.'));
    const filename = Date.now() + suffix;
    file.url = OSSData.dir + filename;

    return file;
  };

  getExtraData = file => {
    const { OSSData } = this.state;

    return {
      key: file.url,
      OSSAccessKeyId: OSSData.accessId,
      policy: OSSData.policy,
      Signature: OSSData.signature,
    };
  };

  beforeUpload = async () => {
    const { OSSData } = this.state;
    const expire = OSSData.expire * 1000;

    if (expire < Date.now()) {
      await this.init();
    }
    return true;
  };

  render() {
    const { value } = this.props;
    const props = {
      name: 'file',
      fileList: value,
      action: this.state.OSSData.host,
      onChange: this.onChange,
      onRemove: this.onRemove,
      transformFile: this.transformFile,
      data: this.getExtraData,
      beforeUpload: this.beforeUpload,
    };
    return (
      <Upload {...props}>
        <Button>
          <Icon type="upload" /> Click to Upload
        </Button>
      </Upload>
    );
  }
}

class FormPage extends React.Component {
  render() {
    const { getFieldDecorator } = this.props.form;
    return (
      <Form onSubmit={this.handleSubmit} labelCol={{ span: 4 }}>
        <Form.Item label="Photos">{getFieldDecorator('photos')(<AliyunOSSUpload />)}</Form.Item>
      </Form>
    );
  }
}

const WrappedFormPage = Form.create()(FormPage);

ReactDOM.render(<WrappedFormPage />, mountNode);

和例子一样用form表单上传的,然后在AliyunOSSUpload组件中

const { value } = this.props

value参数作为上传图片的fileList(我也不知道这个value是怎么来的),我使用this.props.form.validateFields能拿到一开始定义好的值(例子中的photos)但是却拿不到阿里云的那个地址(例子中的getExtraData的那个file.url),监听事件onChange也没有,而且打印出来只有两个参数file fileList而没有event

// onChange 回调参数
{
  file: { /* ... */ },
  fileList: [ /* ... */ ],
  event: { /* ... */ },
}

那么该怎么拿到上传后阿里云的图片地址呢?目的是为了预览以及后续保存操作。

目前想到一个办法就是在getExtraData这一步中加一个fileName然后去把这个地址拼出来,但是我觉得这样不太好希望是能在onChange方法中拿到就好了,求大佬指点一下!

getExtraData = file => {
    const { OSSData } = this.state;
    
    const fileName = file.url
    this.setState({ fileName })
 
    return {
      key: fileName,
      OSSAccessKeyId: OSSData.accessId,
      policy: OSSData.policy,
      Signature: OSSData.signature,
    };
}

另外onChange方法好像监听不到上传失败?阿里云接口返回403onChange里面依然也还是和上传一样的file的状态以及没有event参数。

阅读 4.2k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题