Я исследовал синтетические события в React и понимаю, что React объединяет события для повышения производительности. Я также знаю, что события в React не являются событиями DOM. Я прочитал несколько сообщений и тем на эту тему, но не могу найти упоминания о звонке preventDefault
после звонка event.persist
.
Многие сайты упоминали, что, например, если мы хотим зафиксировать значение 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.
*/
Все источники, с которыми я консультировался, эффективно реализовали либо debounce, либо throttle для захвата значения, а затем что-то сделали с этим значением, но ни один из них не пытался вызвать preventDefault
после persist
, как я пытаюсь сделать. Вот некоторые из этих источников:
- Блог Пост о троттлинге и глушении
- Пример регулирования входа peterbe
- A скрипка , которая делает именно то, к чему я стремлюсь, но это не написано в React