antd 3.x版本Upload组件的onChange回调只执行一次的问题处理

643 阅读1分钟

问题描述

antd 3.x版本Upload组件的onChange回调只执行一次,且info.file.status一直为uploading,http请求正常,返回200。

问题分析

在uploading的时期没有进行setState更新。对于受控模式,应该在 onChange 中始终 setState fileList,保证所有状态同步到 Upload 组件内。

问题解决方法

方法一:

fileList的状态更新不能在状态的判断语句里面

onFileChange = (info) => {
  if ( info.file.status === 'done' ) {
    this.setState({ fileList: [...info.fileList] });
  } else {
    ...
  }
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

把fileList的状态更新挪到判断语句外面

onFileChange = (info) => {
  if ( info.file.status === 'done' ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...info.fileList] });
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

注意需要克隆 fileList 以保障 Upload 能感知数组变化。

- this.setState({ fileList: info.fileList });
+ this.setState({ fileList: [...info.fileList] });

方法二:

使用API:customRequest,实现自定义上传。

handleUpload = (options) => {
  let {fileList} = this.state;
  const _this = this;
  const { file } = options;
  //实现接口,保存上传的文件
  _this.props.actions.****({files: file}, (data) => {
  //获取返回的信息
    if (data && data.res) {
      fileList.push({
        uid: data.res.id,
        name: data.res.name,
        status: 'done',
        url: data.res.url,
      });
      _this.setState({fileList, count});
    }
  })
}  
  
  
<Upload
  fileList={this.state.fileList}
  customRequest={this.handleUpload}
>
  <Button>
    <Icon type="upload" /> 上传附件
  </Button>
</Upload>

上传附件的data数据需要转换成formData的数据形式进行上传,所以要对data数据进行转换:

const formData = new FormData();
Object.keys(data).forEach((key) => {
  if (key === 'files') {
    data[key].forEach(file => {
      formData.append('files[]', file);
    });
  } else {
    formData.append(key, cloneData[key]);
  }
});

设置上传文件的接口的请求头:Content-Type: 'multipart/form-data; boundary=something'