问题:文件上传失败时不需要回显。
思路:添加fileList属性,绑定一个列表,上传成功的文件才加入列表中,代码如下:
const [ imgFileList, setImgFileList ] = useState<any[]>([]);
<Upload
name='upload_file'
action="/file/upload/v4" //这个路径是我项目中封装好的路径接口,根据自己的项目接口替换
accept='image/jpeg,image/jpg,image/png'
fileList={imgFileList}
onChange={resp => {
const _file = resp.file || {};
if(_file.status!=="done") return
// 上传成功
if (_file.response?.status == 0) {
const uid = _file.response?.uid || "";
handleFileListChange([uid]);
}else{
notification["error"]({
message: _file.response?.msg||"上传文件失败,请重新上传"
});
}
}}
>
代码这样写看似没有问题,但实际上执行onChange回调方法的时候,却只执行到了uploading状态,没有接着往下走done状态,这就出现了很大的问题。解决方式如下所示:
...
const [ imgFileList, setImgFileList ] = useState<any[]>([]);
...
<Upload
name='upload_file'
action="/file/upload/v4"
fileList={imgFileList}
...
onChange={resp => {
const _file:any = resp.file || {};
if (_file.status == "uploading") {
// 在这里设置一下需要展示的文件才会继续走到done状态
setImgFileList([_file]);
return;
}else if (["removed","error"].indexOf(_file.status) !== -1) {
// "removed","error"状态时也设置一下
setImgFileList([]);
return;
}
// done状态
// 后端返回状态码为0证明上传成功
if (_file.response?.status == 0) {
const uid = _file.response?.uid || "";
} else {
notification["error"]({
message: _file.response?.msg || "上传文件失败,请重新上传"
});
}
}}
>
在uploading状态里设置下即可往下走done状态
不过这个写法对于我在项目中开发的内容还有些限制,我在开发中,按照上面的内容开发,确实能够上传,不过还是出现了其他问题,不能满足我项目的功能需求,个人建议还是使用我下面的方法比较妥当:
思路:
1、对于upload组件使用showUploadList={false}
取消展示
2、使用useState 定义一个存放上传图片的变量
3、图片上传后,将图片地址存到该变量中
4、自定义一个div,里面使用map遍历文件,用于展示图片
代码如下:
// 这是自定义的div
const imgDiv = (
<div style={{display: 'flex'}}>
{imgFileList.map((item: any) => (
<div style={{position: 'relative'}}>
<div hidden={showDelIcon} className='del' onClick={() => handleDelImg(item)}>
<span className='icon'>X</span>
{/*<CloseCircleOutlined style={{color: '#fff'}} />*/}
</div>
<Image
width={100}
height={100}
src={item.fileUrl} />
</div>
))}
</div>
)
// upload上传组件
<div style={{display: 'flex'}}>
{imgDiv}
<Upload name='upload_file'
listType="picture-card"
showUploadList={false}
action='/file/upload/v4'
headers={{appCode: 'range-land-emp-happy'}}
maxCount={5} accept={'image/jpeg,image/jpg,image/png'}
beforeUpload={handleBeforeUpload}
onPreview={handlePreview}
onRemove={handleRemoveImg}
onChange={handleImgChange}>
{isDisabled ? null : <div>
<PlusOutlined style={{ fontSize: '32px', color: '#D1D1D1' }}/>
<div style={{ marginTop: 10 }}></div>
</div>}
</Upload>
</div>
// 图片上传状态改变回调
const handleImgChange = (info: any) => {
if (info.file.status === 'uploading') {
return;
}
// 图片上传成功,往里面追加一条记录
if (info.file.status === 'done') {
let ext:any = info.file.type.split('/')[1]
const newData = { id: '', rowId: generateUUID(), fileTypeId: '材料图片', fileType:'材料图片', fileName: info.file.name, fileUrl: info.file.response.data.rows[0].url, progress: info.file.percent, fileExt: ext, fileSize: info.file.size}
const { response, response: {status}} = info.file
if (status === 200 && response.data.rows[0]) {
message.success('上传成功')
setImgFileList(() => {
return [...imgFileList, newData]
})
} else {
message.error(response.message || '上传失败')
}
}
}
// 图片上传之前回调
const handleBeforeUpload = (file:any) => {
// 判断上传的是否是图片
if (!judgeImg(file.name)) {
message.warning('请上传图片格式的文件')
return Upload.LIST_IGNORE
}
if (imgFileList.length>=5) {
message.warning('最多上传5张图片')
return Upload.LIST_IGNORE
}
}
按照这个流程上传完全没问题!!