Ant-design: Upload file.status is always being uploading

Created on 18 Jul 2016  ·  90Comments  ·  Source: ant-design/ant-design

本地环境

  • antd 版本:1.6.5
  • 操作系统及其版本:mac 10.11.5
  • 浏览器及其版本:50.0.2661.102

你做了什么?

1.6.5版本 Upload控件onChange方法只会执行一次,且info.file.status一直为uploading,http请求正常,返回200。
降级为1.6.4之后正常使用,uploading之后info.file.status为done

你期待的结果是:

实际上的结果:

可重现的在线演示

Question Usage ❓FAQ

Most helpful comment

对于受控模式,你应该在 onChange 中始终 setState fileList,保证所有状态同步到 Upload 内。类似这里的写法:http://ant.design/components/upload/#components-upload-demo-fileList

// good

onFileChange(fileList) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}

...

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

onFileChange(fileList) {
  if ( ... ) {
    this.setState({ fileList: [...fileList] });
  } else {
    ...
  }
}

...

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

建议研习受控组件概念:https://facebook.github.io/react/docs/forms.html#controlled-components


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

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

All 90 comments

我实测是没有问题的,方便给出有问题的完整代码以方便重现么?

对于受控模式,你应该在 onChange 中始终 setState fileList,保证所有状态同步到 Upload 内。类似这里的写法:http://ant.design/components/upload/#components-upload-demo-fileList

// good

onFileChange(fileList) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}

...

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

onFileChange(fileList) {
  if ( ... ) {
    this.setState({ fileList: [...fileList] });
  } else {
    ...
  }
}

...

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

建议研习受控组件概念:https://facebook.github.io/react/docs/forms.html#controlled-components


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

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

e0a986ed71cd87e506fb8e4ee5e2e0130fc70ae1

我使用Upload控件为什么总是上传失败,总是报错:POST http://localhost:8081/api/nes/2/uploadMusic/r_ty 404 (Not Found)

对于有限制的url怎么去增加身份标识字段和token之类的用action怎么去传?action只给地址,不能加上data么?

在 React.PureComponent 里面还是有问题的 因为React.PureComponent里面做了一层优化判断,filelist有缓存引用, 认为是同一个对象就不会更新, 在React.PureComponent立马 应该生成一个新的对象
handleChange = ({ fileList }) => {
// fixed bug
this.setState({ fileList: fileList.slice() });
}

@afc163

@yongningfu 感谢提示,已更新。

特别提醒一下 : 在使用React shouldComponentUpdate 进行浅比较时,在受控模式当中,即使状态同步到 Upload 内,也不会更新的哦。原因是引用全等===,导致阻止render

上传多张图片,beforeUpload设置上传图片参数限制,onChange获取上传成功的图片列表,上传成功几张图片后,上传一张错误的图片,会将前面上传成功的图片全部清除,请问有什么解决办法吗?

当你回调的时候应该重新设置一下status 比如这样 this.setState( {fileList});

handleChange = (info) => {
console.log(info);

    //把fileList拿出来
    let {fileList} = info;

    const status = info.file.status;
    if (status !== 'uploading') {
        console.log(info.file, info.fileList);
    }
    if (status === 'done') {
        message.success(`${info.file.name} file uploaded successfully.`);
    } else if (status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
    }

    //重新设置state
    this.setState( {fileList});
}

这么说onChange只要是状态有变化,Upload内部就一直在调用,是这样吗

这个问题坑了半天,原来要setState一下。组件不应该设计成这样的,为什么依懒外部状态?

我只想要那个base64码,不跟后台交互,怎么样解决自动向后台发请求的问题哦?

维护这个组件的是个沙雕吧

如果上传失败了,想要显示之前的默认图片,要怎么做呀?

上传失败了,在error处理函数中,call
this.setState({
fileList: intial_list
})
就能显示之前的默认图片

我觉得该组件的上传完成时的回调执行时机可能存在问题,试考虑这样一个情况:

组件关系伪代码:

<Controller>
  <Upload fileList={controller.state.fileList} onUpload={controller.onUpload} />
</Controller>

通过 onUpload 通知父组件 Controller 进行 state 的更新。

但由于 React 的 state 的更新是异步的,在图片上传足够快的情况下,会出现执行顺序为
constroller.onUpload(会调用 controller.setState) -> upload.onSuccess -> upload.componentWillReceiveProps
的情况,导致 upload.onSuccess 执行时 upload 的 state 中没有相应的上传完成的文件。因为 upload 的 state.fileList 更新依赖于 componentWillReceiveProps

因此我觉得该组件目前的受控模式是不可靠的。

可能可行的解决方案:

  1. 在受控模式下,将 onSuccess 等事件的 实际 处理逻辑放到 componentDidUpdate 中进行
  2. 避免将 state.fileList 完全依赖于 props.fileList ,在 组件实例 instance 上维护一份相对独立的 fileList (而非 组件实例的状态 instance.state ),便于处理上传事件

let { file ,fileList } = info;
if(file.size/1024/1024>10){
return
}
console.log(file.status)
if(file.status != "done"){
fileList = []
}
this.setState({
fileList,
},console.log(
this.state.fileList,
this.props.form.getFieldValue('upload')
))
当我添加

let { file ,fileList } = info;
if(file.size/1024/1024>10){
return
}
console.log(file.status)
if(file.status != "done"){
fileList = []
}
this.setState({
fileList,
},console.log(
this.state.fileList,
this.props.form.getFieldValue('upload')
))
当我添加
if(file.status != "done"){
fileList = []
}
onchange之监听一次,去掉就好了,这是为什么呢

这个问题并没解决吧

componentWillReceiveProps生命周期中调用setState显示图片也并不会发生变化

componentWillReceiveProps = (nextProps) => {
    this.setState(() => ({ 
      fileList: [...nextProps.fileList] 
    }));
  }  
// ...
<Upload FileList={this.state.fileList} ...>
//...

@afc163 upload组件上传多个文件的时候只有一个文件能上传成功是什么情况呢? 通过log看info.fileList里的status都是uploading,percent和response都是undefined,但是http请求是200,求帮助

@PTGuan 当然,这个组件就是一个一个上传的,后端API也是一个一个文件接收的,你需要在upload成功后的callback中递归调用upload,才能批量上传。希望能结局你的问题。

这个问题并没有解决+1

antd 3.8+ 依旧只有status='loading'状态,没有done状态,怎么解决的?

有没有官方正式的解决方案 一直uploading ,但onSuccess 能等到正确的http200响应

问题已经解决了,this.setState({ fileList: [...fileList] }); 这句话很重要,有问题的请重点看这个

@EnixCoda ,我貌似遇到了你描述的问题,我上传偶尔会出现一直显示“正在上传中”。

@withzhaoyu 嗯,其实这里大多数人遇到的都是这个问题。这个组件把上传进度通过 React state 来存储是不太可靠的。

怎么解决啊!!!!!!!!!!一直在uploading

遇坑+1

handleUploaderChange = ({file, fileList}) => {
  console.log('file vo =>', file, fileList);
  if (file.status === 'done') {
    fileList = fileList.map((item, index) => {
      // 相关文件对象数据格式化处理
      return item;
    });
  }
   // 避免原来的文件丢失,这样子写就可以了
  this.setState({ fileList: file.status ? [...fileList] : this.state.fileList });
};

// 上传进度可以通过onProgress中的percent来控制样式,而不是file.status
handleProgress = (event, file) => {
  let {fileList} = this.state;
  fileList = fileList.map(item => {
    if (item.uid === file.uid) {
      item.percent = event.percent;
    }
    return item;
  });
  this.setState({fileList});
};

只要读取文件的base64,不需要和后台交互该怎么办

@pingping92

handleChange = ({ file, fileList }) => {
  const { dispatch, nickname } = this.props;
  const reader = new FileReader();
  reader.onload = e => {
    const base64 = e.target.result;
  };
  reader.readAsDataURL(file.originFileObj);
}
<Upload
  onChange={this.handleAvatarChange}
/>

@AngryPowman ,你可以自己在这个组件基础上再封装一个,功能上还有哪些不能满足的呢

弱弱的在这里问一句,新上传的文件默认不提供url是故意设计的吗?

image

搞笑。现在filelist里面的status还是uploading,就算变成了controlled,我还是把状态为uploading设置上去了。问题根本就没解决

请问下上传文件失败标志是从后端返的->file.response.status,这时候组件没有拦截到,走到了done,文件列表已经展示出来了,我想通过后端返的标志把文件列表清空怎么做?

// 踩了坑 看下源码发现自己使用的问题 如下
// 1.state变量命名
// bad

/*
这里为了方便 使用了与后端返回同样的字段 导致出了问题 这里必须用fileList,不然源码中 this.state.fileList获取是空 就会导致在onSuccess中匹配失败,从而不会在触发第二次onChange事件
*/
state = {imgList:[]} 
<Upload fileList={this.state.imgList} onChange={this.onFileChange} />

// goods

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

// 2. onFileChange的参数是一个obj(包含file和fileList 两个属性) 而且在onFileChange函数中必须调用 this.setState({ fileList: [...fileList] });

state = {fileList:[]} 
onFileChange({file,fileList}) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}
<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

Any english by chance? I have this issue to.

@developdeez what's your issue? which version of Ant Design are you using?
I used AntD 3.0 before and worked on this Upload component for a few months. Everything went well for me. I haven't had any issues remained. I did have some issue in the beginning but I eventually fixed all of them. So I'm confident enough to solve all the common issues.

@swordguard , Ant 3.9.3

Issue is basically not being able to control the filelist of the UI. I upload and image and have tried to clear it using a button and no luck.

I made a ticket here as well with some sample code: https://github.com/ant-design/ant-design/issues/12722#event-1913716771

Have you been able to do this?

遇坑 +1, 试了this.setState({ fileList: [...fileList] })没用,PureComponent换Component也没差,status只停在uploading除非props里不放fileList,请教各位大大

遇坑 +1, 试了this.setState({ fileList: [...fileList] })没用,PureComponent换Component也没差,status只停在uploading除非props里不放fileList,请教各位大大

可以试试,把fileList定义为字符串呢 ~~==~~
// always setState
this.setState({ fileList: JSON.stringify([info.file]) });

@pingping92

handleChange = ({ file, fileList }) => {
  const { dispatch, nickname } = this.props;
  const reader = new FileReader();
  reader.onload = e => {
    const base64 = e.target.result;
  };
  reader.readAsDataURL(file.originFileObj);
}
<Upload
  onChange={this.handleAvatarChange}
/>

这个问题没有解决啊. file对象里面没有originFileObj这个属性. 这个属性是不是只有在upload后才会出现? 但是现在就是没有打算向后台upload,直接获得base64内容.

this.setState({ fileList: [...fileList] }); 虽然这样能解决客户端展示的问题

但是 按需求,文件上传后,后台返回一个文件id,我在点击提交时,需要把id回传过去
但是状态一直在uploading,没办法拿到后台接口的响应呢
@afc163

Same issue here. In component Upload the callback in action property is being called but the UploadFile argument comes with an empty originFileObj i.e. undefined . Any clue how to read the file content using the Upload ant component without uploading the file to the backend?

Same issue here. In component Upload the callback in action property is being called but the UploadFile argument comes with an empty originFileObj i.e. undefined . Any clue how to read the file content using the Upload ant component without uploading the file to the backend?

Actually, you don't need originFileObj, just use file object. I think they have removed originFileObj

I am here because I wanted to make sure that I did not add files in my list that did not succeed on upload. In other words, if my file.status === "error" I dont want to display that file in the UI (certainly, do not want to submit that faulty file in the request). I tried to control that with working with my own controlled component and leveraging fileList. I ran into the said issue of file status never changing from "uploading".

So I went back to not using a controlled component because of this issue. I was able to get the desired request by making sure normFile only adds files that are not "error".

normFile = (e) => {
    if (Array.isArray(e)) {
      return e.filter(x => x.status !== "error");
    }
    return e && e.fileList.filter(x => x.status !== "error");
  };
const generationRequestDecorator = getFieldDecorator('generationRequest', {
      rules: [
        {
          required: true,
          message: 'Please upload your config'
        }
      ],
      valuePropName: 'fileList',
      getValueFromEvent: this.normFile,
    });
const props = {
      name: 'file',
      action: '/api/to/upload',
      multiple: true,
      onChange(info) {
        if (info.file.status !== 'uploading') {
          console.log(info.file, info.fileList);
        }
        if (info.file.status === 'done') {
          message.success(`${info.file.name} file uploaded successfully`);
        } else if (info.file.status === 'error') {
          message.error(`${info.file.name} file upload failed.`);
        }
      },
    };
const generationRequestArea = generationRequestDecorator(
      <Upload {...props}>
        <Button>
          <Icon type="upload"/> Click to Upload
        </Button>
      </Upload>
    );

Again, I sincerely hope antd team could consider my suggestion (previously wrote at here):

maintain file upload states on Upload instance rather than instance's state. bc the state is not always updated synchronously!

我后面,将后台返回的数据单独渲染在页面,Upload 永远存放最新上传的

@yoonwaiyan
`handleChange = (info) => {
let fileList = info.fileList;
this.setState({ fileList: fileList.slice() });
if (info.file.status === 'done') {
message.success(info.file.name + " upload success");
fileList = fileList.slice(-1);
fileList = fileList.map((file) => {
if (file.response) {
file.url = file.response.#check your respone and choose your own url back from server#;
}
return file;
});

  fileList = fileList.filter((file) => {
    if (file.response) {
      return file.response.#check your respone and choose your own respone status code back from server# === 200;
    }
    return false;
  });

  this.setState({ fileList });
} else if (info.file.status === 'error') {
  message.error(info.file.name + " upload failed");
}

}`

try this.

这个问题,我也遇到了,在一波测试之后,感觉找到了问题所在,解释一下:

handleChange = info => {
    let fileList = info.fileList;
    fileList.filter(file => file.status === 'done');
    this.setState({fileList});
}

测试情况包括:如果直接在handleChange里进行this.setState({fileList})是正常执行的。

我之前的写法都是类似这种,在筛选之后,导致第一次的执行,把fileList筛选成了空数组。所以导致一直只有uploading一种状态。
我觉得问题点在于:在上传后,如果手动把fileList设置为空数组,会影响onChange事件的继续执行,在稍微修改筛选条件之后,确实解决了遇到的问题。

请问下官方维护,是不是这两个属性间有什么绑定关系? @imxiongying

另外官方案例里,有一个这样带筛选的案例(完全控制的上传列表),不知是不是我的网络有问题,这个案例也是有这个情况。

这个问题,我也遇到了,在一波测试之后,感觉找到了问题所在,解释一下:

handleChange = info => {
    let fileList = info.fileList;
    fileList.filter(file => file.status === 'done');
    this.setState({fileList});
}

测试情况包括:如果直接在handleChange里进行this.setState({fileList})是正常执行的。

我之前的写法都是类似这种,在筛选之后,导致第一次的执行,把fileList筛选成了空数组。所以导致一直只有uploading一种状态。
我觉得问题点在于:在上传后,如果手动把fileList设置为空数组,会影响onChange事件的继续执行,在稍微修改筛选条件之后,确实解决了遇到的问题。

请问下官方维护,是不是这两个属性间有什么绑定关系? @imxiongying

另外官方案例里,有一个这样带筛选的案例(完全控制的上传列表),不知是不是我的网络有问题,这个案例也是有这个情况。

受控情况下,在onChange回调里把fileList 设置为空,Upload组件内部的fileList就更新为空数组了,它内部的onSuccess,onProgress等逻辑里会从fileList找触发事件的file,找不到就不触发onChange回调了

@luruozhou 嗯嗯,是这个样子,不知道大家遇到问题的,是不是这个情况,感觉被官方案例误导了

@yidianier handleProgress 请问这个函数在哪里调用的?

@yidianier handleProgress 请问这个函数在哪里调用的?

onProgress={this.handleProgress}

受控组件和纯外部依赖组件各有各的场景使用,受控组件在ant内是有逻辑控制的,比如点击空白取消下拉框等,这些如果都放在外部受控的话,你们又会感觉特别麻烦, 所以受控组件承担一部分基础逻辑,不是组件设计上的问题,不要抱怨了。。。

@all

@afc163

@yidianier handleProgress 请问这个函数在哪里调用的?

onProgress={this.handleProgress}

thanks

在3.13.1也会出现这个问题 @afc163

@xiaolong1024 #14780

还是出现这个问题,跟rc-form有关系吗?

handleUploaderChange = ({file, fileList}) => {
  console.log('file vo =>', file, fileList);
  if (file.status === 'done') {
    fileList = fileList.map((item, index) => {
      // 相关文件对象数据格式化处理
      return item;
    });
  }
   // 避免原来的文件丢失,这样子写就可以了
  this.setState({ fileList: file.status ? [...fileList] : this.state.fileList });
};

// 上传进度可以通过onProgress中的percent来控制样式,而不是file.status
handleProgress = (event, file) => {
  let {fileList} = this.state;
  fileList = fileList.map(item => {
    if (item.uid === file.uid) {
      item.percent = event.percent;
    }
    return item;
  });
  this.setState({fileList});
};

This answer solved my problem!

在3.13.0版本中,打包之后在onChange中操作this.setState({fileList})会导致上传请求被取消,在开发环境中是正常的,还无法确定原因。

@tsuijie 3.13.5 已修复。

请问作者,我上传以后 拿不到fileOBJ下的response 也就拿不到后端返回的fileid 这样怎么处理呢 。我也是同样的情况,status===uploading

`import React, { Component } from 'react';
import { Upload, Icon } from 'antd';
import {urlMapToFileList, fileListTourlMap} from '@/utils/utils';
import { upLoadFile } from '@/services/api';

class UploadForm extends Component {
static defaultProps = {
hideCheckAll: false,
};

constructor(props) {
super(props);
console.log(urlMapToFileList(props.value));
this.state = {
filesList: urlMapToFileList(props.value) || urlMapToFileList(props.defaultValue) || [],
// value: urlMapToFileList(props.value) || urlMapToFileList(props.defaultValue) || [],
};
}

onChange = value => {
const { onChange } = this.props;
if (onChange) {
const selfValue = fileListTourlMap(value);
onChange(selfValue.length? selfValue : null);
}
};
handleChange = (data) => {
const {file} = data;
const {fileList} = data;
console.log('handleChange', file.status);
if(file.status === 'done') {
debugger
const {response} = file;
if(response && response.success) {
file.url = response.result.url;
fileList.pop();
fileList.push(file);
}
}
if(file.status === 'error') {
fileList.pop();
}

if(!file.status) {
  fileList = fileList.filter(ele => ele.url)
}
this.setState({filesList: fileList});
this.onChange(fileList);

}

render() {
const {filesList} = this.state;
return (

accept="image/*"
headers={{'x-Access-Token': localStorage.getItem('token')}}
action="/api/admin/file/upload"
listType="picture-card"
fileList={filesList}
onChange={this.handleChange}
{...this.porps}
>
{filesList.length >= 1 ? null:

上传
}


);
}
}

export default UploadForm;
`
这种控制上传数量,但上传状态一直为 uploading是啥原因?
@afc163

虽然都是几年前的老问题了,但是今天也踩了一下坑,说一下自己碰到的坑点,如果你用到了React.PureComponent去创建组件,那么请注意他会默认通过 shouldComponentUpdate 这个生命周期进行浅比较,而你的 filelist 这个 state 引用地址是没有变化的,因此upload组件内部是不会变化的。

let fileList = info.fileList;
/* 这里需要改变一下fileList的引用 */
fileList = JSON.parse(JSON.stringify(fileList));
this.setState({ fileList:fileList});

3.16.1 Upload 还是有问题 change只走一次,建议更新下

需要 this.setState({ fileList: fileList.slice() }) 这样才行

3.16.2 在使用React Hook时,在Upload 的onChange中 fileList 需要进行深拷贝
可以使用 lodash _.cloneDeep(fileList)

集成了 mobx, 在一个 Modal 里用了两个 Upload 组件,并且在相应的 store 里定义了两个 fileList, 其中一个Upload 的 onChange 事件走的是正常的上传流程(uploading 和 done 状态都接收到了),但是另一个比较失望,一直只有 uploading,最终只能使用这种方式解决
修改前: this.fileList[0] = file; 修改后: this.fileList = []; this.fileList.push(file);
并且,如果 this.fileList 来自于继承的 class, 用修改后的这种方式也不行

if (status === 'error') {
    message.success(`${file.name} upload failed.`);
    const fileList = this.state.fileList.filter(file => !file.error);
    this.setState({
        fileList
    }, () => {
        console.log(this.state.fileList)
    })
}

在失败的时候我想移除失败的显示项, 通过这种方法为什么state没有改变呢?

console.log是正确的,state已经是空的了, 但是开发者工具还是有,并且上传失败的图片也显示出来了

https://github.com/ant-design/ant-design/issues/2423#issuecomment-491143417

this.setState({
    fileList:[...fileList]
}

对于有限制的url怎么去增加身份标识字段和token之类的用action怎么去传?action只给地址,不能加上data么?

可以放到Header里边

is solved my problem with this trick
Screen Shot 1398-03-25 at 6 29 26

i had dynamic input creation system, so with new dynamic props you can tell antd about incomming props

It fixed to me when I started using React.Component instead of React.PureComponent.

When I use modal.info and control filelist, onChange is only called once. But when I remove Modal, it works

可以

1: 使用React.Component
2: 注意检查getDerivedStateFromProps里面是否设置了fileList,是否设置正确。
3: fileList: this.state.fileList
4: onChange: ({file, fileList}) => {
this.setState({fileList});
}

3.19.7还有这个问题

I post a successful case for your reference. I've had this problem before, though. Also calculate here make a note, in order to facilitate oneself forgot convenient search later

env:

  • antd: 4.0.0-rc.1
  • pro-layout: 5.0.0
  • react: 16.9.17
import React, { useState } from 'react';
import { Modal, Upload, Button, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons/lib';
import { UploadProps } from 'antd/lib/upload';
import { deleteArtifact } from '@/services/artifact';

interface UploadModalType {
  visible: boolean
  onCancel: () => void
  projectId: number
}

const UploadModal: React.FC<UploadModalType> = props => {
  const { visible, onCancel, projectId } = props;
  const [fileList, setFileList] = useState();

  const uploadProps: UploadProps = {
    name: 'file',
    fileList,
    listType: 'text',
    action: 'http://localhost:8080/v1/artifacts',
    data: { project_id: projectId, type: 'application/json' },
    onChange(info) {

      setFileList(info.fileList.slice()); // Note: A new object must be used here!!!

      if (info.file.status === 'done') {
        message.success(`${info.file.name} file uploaded successfully`);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
      }
    },
    onRemove(file) {
      const promise: PromiseLike<void | boolean> = deleteArtifact({ filename: file.response });
      promise.then((value: any) => {
        if (value === '' || value instanceof Response && value.status === 205) {
          const index = fileList.indexOf(file);
          const newFileList = fileList.slice();
          newFileList.splice(index, 1);
          setFileList(newFileList);
        }
      });
    },
  };

  return (
    <Modal
      destroyOnClose
      title='上传归档文件'
      visible={visible}
      onCancel={onCancel}
    >
      <Upload
        {...uploadProps}
      >
        <Button>
          <UploadOutlined/> Click to Upload
        </Button>
      </Upload>
    </Modal>
  );
};

export default UploadModal;

好坑啊,uploading状态必须设置fileList不然,只执行一次,折腾半天,无语死了。

I post a successful case for your reference. I've had this problem before, though. Also calculate here make a note, in order to facilitate oneself forgot convenient search later

env:

  • antd: 4.0.0-rc.1
  • pro-layout: 5.0.0
  • react: 16.9.17
import React, { useState } from 'react';
import { Modal, Upload, Button, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons/lib';
import { UploadProps } from 'antd/lib/upload';
import { deleteArtifact } from '@/services/artifact';

interface UploadModalType {
  visible: boolean
  onCancel: () => void
  projectId: number
}

const UploadModal: React.FC<UploadModalType> = props => {
  const { visible, onCancel, projectId } = props;
  const [fileList, setFileList] = useState();

  const uploadProps: UploadProps = {
    name: 'file',
    fileList,
    listType: 'text',
    action: 'http://localhost:8080/v1/artifacts',
    data: { project_id: projectId, type: 'application/json' },
    onChange(info) {

      setFileList(info.fileList.slice()); // Note: A new object must be used here!!!

      if (info.file.status === 'done') {
        message.success(`${info.file.name} file uploaded successfully`);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
      }
    },
    onRemove(file) {
      const promise: PromiseLike<void | boolean> = deleteArtifact({ filename: file.response });
      promise.then((value: any) => {
        if (value === '' || value instanceof Response && value.status === 205) {
          const index = fileList.indexOf(file);
          const newFileList = fileList.slice();
          newFileList.splice(index, 1);
          setFileList(newFileList);
        }
      });
    },
  };

  return (
    <Modal
      destroyOnClose
      title='上传归档文件'
      visible={visible}
      onCancel={onCancel}
    >
      <Upload
        {...uploadProps}
      >
        <Button>
          <UploadOutlined/> Click to Upload
        </Button>
      </Upload>
    </Modal>
  );
};

export default UploadModal;

I have the same problem using Func component. Info.status always has uploading status and onChange calls only once

@tsuijie 3.13.5 已修复。

3.13.5 我也出现了同样的问题 onChange中操作this.setState({fileList})会导致上传请求被取消

如果没有使用其action接口,在上传后会出现一直上传中的状态,需要手动将每个文件的status设置为done

如果没有使用其action接口,在上传后会出现一直上传中的状态,需要手动将每个文件的status设置为done

请检查fileList回写state时有没有使用新对象,[...fileList]

好的  谢谢

---Original---
From: "Amumu"<[email protected]>
Date: Sun, Jul 26, 2020 17:59 PM
To: "ant-design/ant-design"<[email protected]>;
Cc: "Comment"<[email protected]>;"SCLGIS"<[email protected]>;
Subject: Re: [ant-design/ant-design] Upload file.status is always being uploading (#2423)

如果没有使用其action接口,在上传后会出现一直上传中的状态,需要手动将每个文件的status设置为done

请检查fileList回写state时有没有使用新对象,[...fileList]


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

It doesn't work if I use hooks with the "multiples" options enabled.
If I select 3 files, I get 2 on the list. If I select 5 files, I get only 3, sometimes 4. If I remove the prop "fileList", it works fine, and I can see all the files on the list, but I can't control them - I need to use the "fileList" prop.
I have a different behavior if I use class component instead of the hook useState.

在4.5.1上也遇到这个问题,一直是uploading的状态。试了前面大佬说的方法都没用,最后看了源码发现是因为我render时每次的upload组件的key值不一样,导致重新渲染了,源码默认就取消了前面的上传请求,导致一直是uploding的状态,key值固定然后就正常可以上传成功了

@tsuijie 3.13.5 已修复。

3.13.5 我也出现了同样的问题 onChange中操作this.setState({fileList})会导致上传请求被取消

Was this page helpful?
0 / 5 - 0 ratings

Related issues

benjycui picture benjycui  ·  65Comments

zombieJ picture zombieJ  ·  182Comments

davidebianchi picture davidebianchi  ·  187Comments

TangMonk picture TangMonk  ·  78Comments

zlab picture zlab  ·  223Comments