问题描述
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';