簡體   English   中英

在React中調用event.persist()之后,調用event.preventDefault()

[英]Call event.preventDefault() after calling event.persist() in React

我已經在React中研究了綜合事件,並且我知道React會合並事件以提高性能。 我也知道React中的事件不是DOM事件。 我已經閱讀了有關此主題的幾篇文章和主題,但是在調用event.persist之后找不到關於調用preventDefault任何提及。

例如,許多站點都提到,如果我們想捕獲event.target的值, event.target該選項只是將其緩存以備后用,但這不適用於我的用例。

我想限制正在監聽onDragOver事件的事件處理程序。 為了在React中做到這一點,我必須通過3個函數傳遞事件,在第一個函數上調用event.persist ,以便最后一個可以看到它。

但是,當我調用它時, event.preventDefault無效。 就像一旦我們調用event.persist ,就這樣,沒有回頭路可走了。

下面是一些代碼,但您可能會發現在StackBlitz上進行試驗更有用。

import React, { Component } from 'react';
import { throttle } from 'throttle-debounce';
import DropItem from './DropItem';

class DropZone extends Component {
  constructor(props) {
    super(props);
    this.onDragOverThrottled = throttle(500, this.onDragOver);
    this.onDragStart = this.onDragStart.bind(this);
    this.handleDragOver = this.handleDragOver.bind(this);
  }

  onDragStart(e, id) {
    console.log('dragstart: ', id);
    e.dataTransfer.setData("id", id);
  }

  onDragOver(e) {
    e.preventDefault();  // this does nothing if event.persist fires before it
    console.log('dragover...');
  }

  handleDragOver(e) {
    e.persist();
    this.onDragOverThrottled(e);
  }

  render() {
    const items = this.props.items.map((item, index) => {
      return <DropItem item={item} key={index} onDragStart={this.onDragStart} />;
    });

    return (
      <div
        className={this.props.class}
        //onDragOver={this.handleDragOver}  // See note 1 below
        onDragOver={this.onDragOver}  // See note 2 below
        onDrop={(e) => {this.props.onDrop(e, this.props.location)}}>
        <span className="task-header">{this.props.title}</span>
        {items}
      </div>
    );
  }
}

export default DropZone;

/*

NOTE 1
Commenting in this line shows that throttling works but preventDefault does not and we cannot drag and drop any box to another location.

NOTE 2
This skips throttling altogether but preventDefault does work which allows the box to be moved to a different area. Because throttling is disabled here, onDragOver fires a lot and, at times, keeps the user from moving boxes around quickly.

*/

我咨詢過的所有資源都有效地實現了反跳或限制以捕獲值,然后使用該值執行某些操作,但是沒有一個在我嘗試執行的persist之后嘗試調用preventDefault 其中一些來源如下:

經過進一步的研究和實驗,我找到了解決方法。

TL; DR
我的理論認為event.persist()某種程度上阻止了event.preventDefault()正常工作,這是不正確的。

真正的問題
我的拖放應用程序無法進行節流的原因是event.persist()不會將事件轉發給另一個處理程序,而只是使其可供其他處理程序訪問。 這意味着必須在使用該事件的每個處理程序上調用event.preventDefault() 現在我說了這似乎很明顯,但是由於我必須通過多個處理程序發送事件以實現限制,所以我錯誤地認為我將事件從一個傳遞到另一個。

文件資料
我上面所說的只是我的觀察,並非來自React的官方文檔。 但是React文檔確實這么說:

如果要以異步方式訪問事件屬性,則應在事件上調用event.persist() ,這將從池中刪除綜合事件,並允許用戶代碼保留對該事件的引用。

盡管我以前讀過這篇文章,但由於我不認為自己正在做異步事情,所以我跳過了它。 但是答案仍然就在這里,它允許用戶代碼保留對事件的引用

學到更多
對於那些想深入研究的人,請務必查看我的StackBlitz中的README ,我將在其中提供更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM