New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload file.status is always being uploading #2423

Closed
imxiongying opened this Issue Jul 18, 2016 · 47 comments

Comments

Projects
None yet
@imxiongying

imxiongying commented Jul 18, 2016

本地环境

  • 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

你期待的结果是:

实际上的结果:

可重现的在线演示

@afc163

This comment has been minimized.

Member

afc163 commented Jul 19, 2016

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

@imxiongying

This comment has been minimized.

imxiongying commented Jul 19, 2016

@afc163

This comment has been minimized.

Member

afc163 commented Jul 19, 2016

对于受控模式,你应该在 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

@afc163

This comment has been minimized.

Member

afc163 commented Oct 11, 2016

@hull123

This comment has been minimized.

hull123 commented Mar 2, 2017

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

@Adam-Ggogoing

This comment has been minimized.

Adam-Ggogoing commented Apr 28, 2017

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

@yongningfu

This comment has been minimized.

yongningfu commented Jun 8, 2017

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

@afc163

@afc163

This comment has been minimized.

Member

afc163 commented Jun 8, 2017

@yongningfu 感谢提示,已更新。

@TongDaDa

This comment has been minimized.

TongDaDa commented Sep 20, 2017

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

@bang0929

This comment has been minimized.

bang0929 commented Dec 21, 2017

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

@SummerSMJ

This comment has been minimized.

SummerSMJ commented Jan 25, 2018

当你回调的时候应该重新设置一下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});
}
@hoozi

This comment has been minimized.

hoozi commented Mar 28, 2018

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

@wv1124

This comment has been minimized.

wv1124 commented Apr 28, 2018

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

@fengyansuowang

This comment has been minimized.

fengyansuowang commented May 9, 2018

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

@leleniu

This comment has been minimized.

leleniu commented Jul 12, 2018

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之监听一次,去掉就好了,这是为什么呢

@zgdmm

This comment has been minimized.

zgdmm commented Jul 25, 2018

这个问题并没解决吧

@Tommy-White

This comment has been minimized.

Tommy-White commented Jul 31, 2018

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

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

This comment has been minimized.

PTGuan commented Aug 20, 2018

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

@swordguard

This comment has been minimized.

swordguard commented Aug 20, 2018

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

@SUH11

This comment has been minimized.

SUH11 commented Aug 24, 2018

这个问题并没有解决+1

@jett87

This comment has been minimized.

jett87 commented Aug 24, 2018

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

@jett87

This comment has been minimized.

jett87 commented Aug 25, 2018

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

@jett87

This comment has been minimized.

jett87 commented Aug 25, 2018

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

@withzhaoyu

This comment has been minimized.

withzhaoyu commented Sep 6, 2018

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

@EnixCoda

This comment has been minimized.

EnixCoda commented Sep 6, 2018

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

@thiswhy

This comment has been minimized.

thiswhy commented Sep 11, 2018

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

@AntoninSorrento

This comment has been minimized.

AntoninSorrento commented Sep 12, 2018

遇坑+1

@yidianier

This comment has been minimized.

yidianier commented Sep 12, 2018

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});
};
@pingping92

This comment has been minimized.

pingping92 commented Sep 20, 2018

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

@dengfuping

This comment has been minimized.

Contributor

dengfuping commented Sep 20, 2018

@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}
/>
@yidianier

This comment has been minimized.

yidianier commented Sep 25, 2018

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

@yoyo837

This comment has been minimized.

Contributor

yoyo837 commented Sep 25, 2018

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

image

@alivelee

This comment has been minimized.

alivelee commented Oct 7, 2018

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

@zhangzhi93

This comment has been minimized.

zhangzhi93 commented Oct 12, 2018

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

@zwStar

This comment has been minimized.

zwStar commented Oct 13, 2018

// 踩了坑 看下源码发现自己使用的问题 如下
// 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} />
@developdeez

This comment has been minimized.

developdeez commented Oct 19, 2018

Any english by chance? I have this issue to.

@swordguard

This comment has been minimized.

swordguard commented Oct 19, 2018

@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.

@developdeez

This comment has been minimized.

developdeez commented Oct 19, 2018

@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: #12722 (comment)

Have you been able to do this?

@afc163 afc163 changed the title from 1.6.5版本 Upload控件 bug to Upload file.status is always being uploading Nov 2, 2018

@afc163 afc163 added the FAQ label Nov 2, 2018

@yoonwaiyan

This comment has been minimized.

yoonwaiyan commented Nov 12, 2018

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

@rhett-web

This comment has been minimized.

rhett-web commented Nov 23, 2018

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

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

@popmanhe

This comment has been minimized.

popmanhe commented Dec 14, 2018

@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内容.

@shunzizhan

This comment has been minimized.

shunzizhan commented Dec 15, 2018

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment