我有一个可单击的dropZone,打开了文件选择项。一旦从您的计算机中选择了一个文件,它就会对其进行预览(如果它是图像)。我希望能够拖放相同的文件,并且执行与单击div并打开文件一样的操作。

我尝试在handleChange内调用我的onDrop函数,但是它无法正常工作,并且会出现TypeError: Cannot read property 'target' of undefined错误,或者它根本什么也不做。 Here is a CodeSandbox of the dropzone component on it's own.

这是我的代码片段:

class DropZone extends Component {

  constructor(props){
    super(props)
    this.state = {
      file: "",
      fileId: uuid(),
      className: 'dropZone'
    }
    this.handleChange = this.handleChange.bind(this)
    this._onDragEnter = this._onDragEnter.bind(this);
    this._onDragLeave = this._onDragLeave.bind(this);
    this._onDragOver = this._onDragOver.bind(this);
    this._onDrop = this._onDrop.bind(this);
  }

  handleChange(event) {
    this.setState({
      file: URL.createObjectURL(event.target.files[0])
    })
    console.log("handleChange")
    //document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
  }

  componentDidMount() {
    window.addEventListener('mouseup', this._onDragLeave);
    window.addEventListener('dragenter', this._onDragEnter);
    window.addEventListener('dragover', this._onDragOver);
    document.getElementById('dragbox').addEventListener('dragleave', this._onDragLeave);
    window.addEventListener('drop', this._onDrop);
  }

  componentWillUnmount() {
    window.removeEventListener('mouseup', this._onDragLeave);
    window.removeEventListener('dragenter', this._onDragEnter);
    window.addEventListener('dragover', this._onDragOver);
    document.getElementById('dragbox').removeEventListener('dragleave', this._onDragLeave);
    window.removeEventListener('drop', this._onDrop);
  }

  _onDragEnter(e) {
    e.stopPropagation();
    e.preventDefault();
    return false;
  }

  _onDragOver(e) {
    e.preventDefault();
    e.stopPropagation();
    return false;
  }

  _onDragLeave(e) {
    e.stopPropagation();
    e.preventDefault();
    return false;
  }

  _onDrop(e, event) {
    e.preventDefault();
    this.handleChange
    let files = e.dataTransfer.files;
    console.log('Files dropped: ', files);
    // Upload files
    //this.handleChange.bind(this)
    console.log(this.state.file)
    return false;
  }

render() {
  const uniqueId = this.state.fileId;
  return (
    <div>
      <input type="file" id={uniqueId} name={uniqueId} class="inputFile" onChange={this.handleChange}/>
      <label   htmlFor={uniqueId} value={this.state.file}>
      {this.props.children}
        <div className="dropZone" id="dragbox" onChange={this.handleChange}>
          Drop or Choose File
          <img src={this.state.file} id="pic" name="file" accept="image/*"/>
        </div>
      </label>
      <div>
    </div>
    </div>
  );
}
}


其中将有多个上传自己的个人照片/文件。谢谢!

最佳答案

您需要将e参数传递给handleChange()并正确地从事件中获取文件。

onDrop

_onDrop(e, event) {
    e.preventDefault();
    this.handleChange(e.dataTransfer.files[0]);
    let files = e.dataTransfer.files;
    console.log("Files dropped: ", files);
    // Upload files
    console.log(this.state.file);
    return false;
}


handleChange

handleChange(file = "") {
    this.setState({
      file: URL.createObjectURL(file)
    });
    //document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
}


然后在render中解析事件以获取文件:
onChange={e => this.handleChange(e.target.files[0])}

或者,您可以进行两个handleChange来清理您的render方法。

链接到工作示例:https://codesandbox.io/s/7k6y94k6w6(基于您的代码)

10-07 13:27