首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在加载文件项目后仅从dataTransfer调度FileList

如何在加载文件项目后仅从dataTransfer调度FileList
EN

Stack Overflow用户
提问于 2016-10-26 10:58:03
回答 3查看 4.1K关注 0票数 4

我使用了一个名为react-dropzone和React-Redux的Node包模块,允许用户将文件拖放到窗口上并显示文件信息。

react-dropzone组件为我提供了来自标准event.dataTransfer.files的FileList。

我遇到的问题是,当我将FileList发送到Redux存储时,文件项还没有加载到FileList数组中,所以当我发送文件数据时,我只得到了{"preview":"blob:file:///f30eafb8-8a77-4402-9111-379590b4a03f"}

如果我将文件项记录到控制台上,它们会很好地显示出来,因为当我查看它们时,它们的数据已经加载了,但是我不知道如何在加载文件信息之后才将其分派出去。

以下是我将其中一个文件项从FileList阵列记录到控制台时所看到的示例。

代码语言:javascript
复制
{
  lastModified: 1473709614000,
  lastModifiedDate: Mon Sep 12 2016 12:46:54 GMT-0700 (PDT),
  name: "test_image.jpg",
  path: "/Users/mitchconquer/Desktop/test_image.jpg",
  preview: "blob:file:///0fe69686-125d-464a-a0a8-a42e497d3808",
  size: 41805,
  type: "image/jpeg",
  webkitRelativePath: ""
}

我认为问题只是File对象没有完全加载,但我不能想出一种方法,只在数据完全加载后才触发操作。谁能给我指一条正确的路?

下面是我使用react-dropzone的组件:

代码语言:javascript
复制
// FileDrop.js
import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import styles from './Home.css';
import Dropzone from 'react-dropzone';

export default class FileDrop extends Component {
  static propTypes = {
    message: PropTypes.string.isRequired,
    setFile: PropTypes.func.isRequired
  };

  onDrop(files, event) {
    console.log({files});
    this.props.setFile(files);
  }

  render() {
    return (
      <div>
        <Dropzone onDropAccepted={this.onDrop.bind(this)} multiple={false} disablePreview={false}>
          <div>{this.props.message}</div>
        </Dropzone>
      </div>
    );
  }
}

...and下面是我的操作文件,其中包含在上面的onDrop方法中使用的setFile方法:

代码语言:javascript
复制
// actions/files.js
export const SET_FILE = 'SET_FILE';

// ACTION CREATORS

function _setFile(file) {
  return {
    type: SET_FILE,
    file
  };
}

// ACTION CREATOR CREATORS

export function setFile(file) {
  return _setFile(file[0]);
}

...and下面是处理该操作的reducer:

代码语言:javascript
复制
// reducers/files.js
import { SET_FILE } from '../actions/files';

export const initialState = [];

export default function files(state = initialState, action = {}) {
  switch (action.type) {
    case SET_FILE:
      const newState = state.slice();
      const file = action.file;
      newState.push(file);
      return newState;
    default:
      return state;
  }
}
EN

回答 3

Stack Overflow用户

发布于 2016-12-20 01:56:14

对于那些有这个问题的人,对于我来说,我认为问题是文件列表中的文件并不像我认为的那样是“普通的JavaScript对象”,而是实际上的文件/Blobs。

我不确定细节--如果有人能解释一下,我会很高兴--但我想我知道的是,blob不像标准JS对象那样有键,所以您不能只是把它推到Redux存储中,然后看到我所期望的属性(lastModified, lastModifiedDate, name, path, preview, size, type, webkitRelativePath)的键值对。

如果您只查看blob,它们唯一的属性是preview,因为这是由React Dropzone在文件/Blob上专门设置的属性。要查看其他属性,必须调用blob上的每个属性。

这是我下面解决方案的简化版本。我接受Filelist数组,创建一个新对象来设置键值,遍历每个键,并用它在newFile对象上的属性设置它。最后,我返回这个对象。然后,您可以在您的存储中设置该对象,它将拥有处理文件所需的数据。

代码语言:javascript
复制
onDrop(files) {
    const fileBlob = files[0];
    const newFile = {};
    _fileProperties.forEach(key => {
      newFile[key] = fileBlob[key];
    });

   return newFile;
}

const _fileProperties = [
  'lastModified',
  'lastModifiedDate',
  'name',
  'path',
  'preview',
  'size',
  'type',
  'webkitRelativePath'
];

可能有很多更好的方法来做到这一点,我确信我的理解是错误的,所以如果有人能更好地解释这一点,我仍然会很高兴。在此期间,这个解决方案对我很有效。

还有一些其他地方可以获得更多信息,比如MDN's File drag and drop文章。

票数 3
EN

Stack Overflow用户

发布于 2018-01-26 15:48:26

我也有同样的问题。我尝试了@Mitch Conquer提供的解决方案和@Ishmael Smyrnow提供的评论,但它返回的是普通对象而不是File对象。同样,正如here所讨论的,不建议将不可序列化的对象存储在存储中。因此,我所做的是,首先只使用FileReader将文件转换为base64并进行存储。

代码语言:javascript
复制
const reader = new FileReader();
reader.readAsDataURL(file);

然后转换回文件作为here提供的解决方案。

代码语言:javascript
复制
export const dataURLtoFile = (dataurl, filename) => {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}
票数 0
EN

Stack Overflow用户

发布于 2018-05-04 22:29:56

我调整了onDrop属性,如下所示:onDrop={this.onDrop},并将文件属性添加到我的方法中-这对我有效。

我认为上面不太起作用的原因是因为我的组件中有其他输入元素-文件上传只是我正在捕获的集合的一部分。

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40252955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档