react-dropzone:在拖动处于活动状态时检查文件

时间:2018-04-24 09:06:38

标签: reactjs react-dropzone

我使用react-dropzone使用拖放功能构建了一个文件上传组件。

我想检查文件,用户拖动到dropzone并执行,而它们被拖动( 之前它们被拖放到dropzone上)。< / p>

我试过了:

<Dropzone
  accept="application/pdf"
  onDrop={this.handleDragDrop}
>
  {({ draggedFiles, isDragActive, isDragReject, acceptedFiles, rejectedFiles }) => {
    if (isDragActive) {
      ... inspect files here (before dropping)
    }
  }}
</Dropzone>

draggedFilesacceptedFilesrejectedFiles没有任何价值。

我在这里错过了什么......?

编辑:

让我的问题更清楚:

我希望在用户将文件放到dragzone之前对文件进行验证。通过将mimetypes传递给accept属性进行验证在我的场景中并不适用:

  1. 用户正在dragzone上拖动文件,而onDragOver被解雇
  2. 现在检查文件并更新dragzone以显示消息files are okfiles not ok,以便用户获取此信息之前他放弃了文件
  3. 用户正在删除文件并触发onDrop

3 个答案:

答案 0 :(得分:0)

你需要使用this.state = { files: [] }初始化你的状态并处理函数中的drop文件:onDrop(files) { // do stuff with files... }

这是文档https://react-dropzone.js.org/的示例摘录:

class Basic extends React.Component {
  constructor() {
    super()
    this.state = { files: [] }
 }

 onDrop(files) {
   this.setState({
     files
   });
 }

 render() {
   return (
     <section>
    <div className="dropzone">
      <Dropzone onDrop={this.onDrop.bind(this)}>
        <p>Try dropping some files here, or click to select files to upload.</p>
      </Dropzone>
    </div>
    <aside>
      <h2>Dropped files</h2>
      <ul>
        {
          this.state.files.map(f => <li key={f.name}>{f.name} - {f.size} bytes</li>)
        }
      </ul>
    </aside>
  </section>
);
}}

答案 1 :(得分:0)

简短回答

AFAIK你不能

长答案

让我们看下面的代码:

<Dropzone 
  accept="image/*,application/pdf" 
  maxSize={5000000}
  onDrop={this.onDrop}
  onDragEnter={this.onDragEnter}
>
  {({getRootProps, getInputProps, isDragAccept, isDragReject }) => {
    let classes = 'form-control'
    let placeholder = <p>Drag files here</p>;
    if (isDragAccept) {
      classes = `${classes} border-success bg-light`;
      placeholder = <p className="text-success">Drop files now</p>;
    } 
    if (isDragReject) {
      classes = `${classes} border-danger bg-light`;
      placeholder = <p className="text-danger">Some files are not allowed</p>
    }
    return (
      <div {...getRootProps()} style={{ height: '100px' }} className={classes}>
        <input {...getInputProps()} />
        {placeholder}
      </div>
    );
  }}
</Dropzone>

如果要删除的文件满足某些要求(任何图像类型或pdf文件且大小小于5MB),此代码段将更改放置区的样式。如果将任何文件拖到拖放区上,则acceptedFilesrejectedFiles的值都是一个空数组。 draggedFiles的值是DataTransferItems的数组,为我们提供了要拖动的文件的kindtype,例如{kind: "file", type: "application/pdf"}

此时,根据文件的类型设置isDragAcceptisDragReject的值。因此,如果我们拖动图像或pdf文件,将值isDragAccept设置为true,则文本Drop files now将显示在拖放区中,其边框将根据类{{ 1}}。但是,如果文件大于5MB,也会发生同样的情况!为什么?这是因为我们无法在放置事件之前读取文件。

让我们看看事件处理程序:

border-success

拖动事件为我们提供了一个dataTransfer对象的DataTransfer属性。在这里,我们有两个对我们很重要的属性:

  • onDrop = (acceptedFiles, rejectedFiles, event) => { console.log(event.dataTransfer.items) console.log(event.dataTransfer.files) } onDragEnter = (event) => { console.log(event.dataTransfer.items) console.log(event.dataTransfer.files) }

    这是一个DataTransferItemList对象,为我们提供了DataTransferItems的列表。它与DataTransfer.items数组中的对象相同,我们可以在两个处理程序onDragEnter和onDrop中访问它。

  • draggedFiles

    这包含拖动操作的FileList对象,但是在拖动事件中它为空,因此我们只有在放置操作之后才能访问它。例如,在前面的代码中,如果我们拖放一些文件,我们将获得以下事件的控制台日志输出:

DataTransfer.files

如果在删除之后访问“文件”列表的元素0,则会得到:

FileList {length: 0} // dragEnter event
FileList {0: File(30299626), length: 1} // drop event

因此,我们只能在放置事件之后中访问文件的数据。

答案 2 :(得分:0)

执行此操作(反应):

  onDragOverHandle(event) {
    event.stopPropagation();
    event.preventDefault();
    console.log(event.dataTransfer.items[0])
  }

您可以获取拖动目标类型,例如:

{kind: "file", type: "image/png"}{kind: "file", type: "video/mp4"}

然后您可以做自己想做的事。

希望能帮助您〜