2

我正在尝试在我的应用程序上实现 Dropzone,但如果照片作为多个输入放置,我将无法预览它们。如果我一个一个地添加它们,它工作正常,但如果我选择多个,只有第一个被渲染。

这是我的 onDrop 功能

onDropGeneral = (currentGeneralPhoto) => {
 let index;
 for (index = 0; index < currentGeneralPhoto.length; ++index) {
  const file = currentGeneralPhoto[index];
  this.setState({
    previewGeneralPhotos: this.state.previewGeneralPhotos.concat(file)
  });
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = (event) => {
    console.log('URL: ', event.target.result);
    this.setState({
      generalPhotos: this.state.generalPhotos.concat([{ base64: event.target.result }])
    });
  };
 }
}

这是我的渲染方法:

<h2>Dropped files</h2>
{this.state.previewGeneralPhotos.length > 0 ? <div>
  <h2>Preview {this.state.previewGeneralPhotos.length} files...</h2>
  <div>{this.state.previewGeneralPhotos.map((file) => <img src={file.preview} alt="preview failed" />)}</div>
 </div> : null}
 <h2> Upload {this.state.generalPhotos.length} Files </h2>

上传计数显示数组的正确大小,但预览计数仅计算丢弃的第一张照片

4

1 回答 1

1

所以你的问题是因为setState可以是异步的。setState你应该在你的函数中使用如下的函数回调onDropGeneral

this.setState(({ previewGeneralPhotos }) => ({
  previewGeneralPhotos: previewGeneralPhotos.concat(file)
}))

这将确保您不会意外覆盖之​​前的值,previewGeneralPhotos并且您实际上会按照您的意图添加到现有数组中。

其他几个建议:

  • 确保你的img元素有一个键。
  • 我会为整个组件使用文件阅读器的一个实例,而不是每次onDropGeneral调用您的方法时都创建一个新的。您可以为 'load' 事件附加一个事件侦听器,componentDidMount并在componentWillUnmount. 至少,最好在调用之前reader.readAsDataURL附加该事件侦听器。
于 2017-06-30T16:05:14.260 回答