如何附加阻力&将事件侦听器拖放到 React 组件

我正在构建一个允许将本地文件拖放到 div 上的组件.然后输出有关已删除文件的信息.

我的问题是我不知道如何在创建组件时正确附加事件侦听器 dropdragover.

我的 App 组件是我所有逻辑所在的地方(用于放置和拖动的处理程序),我创建了一个单独的组件,文件将被放置在该组件上 - dropZone 组件.

我尝试使用 componentDidMount 将事件侦听器放在我的 App 组件上的 dropZone 标记上,如果我的 dropZone 组件已被渲染,则在其上放置一个事件侦听器:

componentDidMount(){常量 dropZone = document.getElementById('dropZone');dropZone.addEventListener('dragover', this.allowDrop.bind(this))dropZone.addEventListener('drop', this.dropHandler.bind(this))}

这没用

然后我尝试将它放在我的应用组件上的 dropZone 标记中:

<DropZone dropZone = {"dropZone"} onDragOver = {this.allowDrop.bind(this)}onDrop ={this.dropHandler.bind(this)} ></DropZone>

这也没有向 dropZone 添加事件侦听器.我已经尝试了其他一些方法,但这些都是我应该工作的.

所以我的问题是,

  • 如何将 dropdragover 事件侦听器添加到 dropZone?

  • 我应该在 App 上添加这些事件监听器并将它们作为道具传递给 dropZone 组件吗?或者根本不需要传下去

  • 或者我应该直接在 dropZone 上添加事件侦听器,这样我的事件处理函数就存在于 dropZone 组件中?

解决方案

你不需要使用道具.您可以在 DropZone 组件中添加所有事件.

http://codepen.io/jzmmm/pen/bZjzxN?editors=0011

这是我添加事件的地方:

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

你的渲染方法:

 渲染() {返回 (

{this.props.children}<div id="dragbox" className={this.state.className}>删除要上传的文件</div></div>);}

正如您在 componentDidMount 中看到的,我也向 #dragbox 添加了一个事件监听器.因为一旦您将文件拖到页面上,#dragbox 就会在鼠标光标下方,因此它需要一个 dragleave 以防您决定不想将文件拖放到那里.

另外,需要 dragover 来捕获 drop

然后在我的 App 组件中,我可以这样使用它:

class App 扩展 React.Component {使成为() {返回 (<拖放区>

<h1>将文件拖到此处...</h1></div></DropZone>);}}

I'm building a component that allows local files to be dragged and dropped on a div. Then there's an output of information about the dropped file.

My problem is I don't know how to properly attach the event listeners drop and dragover when creating my component.

My App component is where all where all my logic is (handler for drop and dragover) and I created a separate component where files will be dropped on - dropZone component.

I tried putting the event listener on the dropZone tag on my App component with a componentDidMount where if my dropZone component had been rendered put an event listener on it:

componentDidMount(){
      const dropZone = document.getElementById('dropZone');
      dropZone.addEventListener('dragover', this.allowDrop.bind(this))
      dropZone.addEventListener('drop', this.dropHandler.bind(this))
    } 

this didn't work

I then tried putting it in my dropZone tag that lives on my app component:

<DropZone dropZone = {"dropZone"} onDragOver = {this.allowDrop.bind(this)} 
 onDrop ={this.dropHandler.bind(this)} >      
</DropZone>

this didn't add an event listener to dropZone either. I've tried a couple of other things but these are the ones that I though should've worked.

So my questions are,

  • how do I add the drop and dragover event listeners to dropZone?

  • Should I be adding these event listeners on App and passing them to dropZone component as a prop? Or is no passing down even necessary

  • Or should I be adding the event listeners on dropZone directly and so my event handler functions live in the dropZone component?

解决方案

You don't need to use props. You can just add all the events inside your DropZone component.

http://codepen.io/jzmmm/pen/bZjzxN?editors=0011

This is where i add the events:

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

Your render method:

  render() {
    return (
      <div>
        {this.props.children}
        <div id="dragbox" className={this.state.className}>
          Drop a file to Upload
        </div>
      </div>
    );
  }

As you can see in componentDidMount, i added an eventlistener to #dragbox as well. Because once you drag a file over the page, #dragbox is under the mouse cursor, so it needs a dragleave in case you decide you don't want to drop the file there.

Also, dragover is needed to capture the drop

Then in my App component, i can use it like this:

class App extends React.Component {
  render() {
    return (
      <DropZone>
        <div>
          <h1>Drag A File Here...</h1>
        </div>
      </DropZone>
    );
  }
}

相关文章