Хук useDrop является ключевым
инструментом библиотеки React Aria для реализации
функционала drag-and-drop. Он позволяет создавать зоны сбрасывания,
которые корректно взаимодействуют с элементами перетаскивания, управляют
состояниями и обеспечивают доступность (accessibility) интерфейса.
useDrop предоставляет набор свойств и колбеков, которые
позволяют:
import {useDrop} from '@react-aria/dnd';
import {useRef} from 'react';
function DropZone({onDrop}) {
const ref = useRef();
const {dropProps, isDropTarget} = useDrop({
onDrop,
accepts: ['text', 'image'],
}, ref);
return (
<div {...dropProps} ref={ref} style={{border: isDropTarget ? '2px solid blue' : '2px dashed gray', padding: '20px'}}>
Перетащите сюда элементы
</div>
);
}
useDroponDrop – функция, вызываемая при
успешном сбросе элемента. Получает объект с данными перетаскиваемого
элемента.accepts – массив типов данных, которые
зона готова принимать. Позволяет фильтровать элементы по их типу.onEnter – колбек, срабатывающий при
наведении перетаскиваемого элемента на зону. Используется для визуальной
подсветки или подготовки состояния.onLeave – вызывается при уходе
элемента с зоны сброса, часто используется для отмены визуальных
эффектов наведения.onDropChange – срабатывает при
изменении состояния сброса, например, когда элемент стал допустимым для
броска.useDrop предоставляет объект состояния с ключевыми
флагами:
isDropTarget – true, если
в данный момент на зону наведён элемент, подходящий для сброса.isActive – true, когда
элемент перетаскивается и зона готова принять его.dropEffect – определяет действие,
которое будет выполнено (copy, move,
link).Эти состояния позволяют динамически изменять стили зоны, обеспечивая визуальную обратную связь.
<div
{...dropProps}
ref={ref}
style={{
border: isDropTarget ? '2px solid green' : '2px dashed gray',
backgroundColor: isActive ? '#e0ffe0' : '#fff',
padding: '20px'
}}
>
Перетащите элемент сюда
</div>
useDragДля полноценной системы drag-and-drop зоны сброса часто комбинируются
с элементами, использующими useDrag.
Взаимодействие осуществляется через типы данных:
import {useDrag} from '@react-aria/dnd';
function DraggableItem({type, data}) {
const ref = useRef();
const {dragProps} = useDrag({
type,
getItems: () => [{...data}],
}, ref);
return (
<div {...dragProps} ref={ref} style={{padding: '10px', border: '1px solid black'}}>
Перетащи меня
</div>
);
}
Важно, чтобы accepts в зоне сброса совпадал с
type элемента, иначе сброс не будет возможен.
React Aria обеспечивает автоматическую поддержку доступности для зон сброса:
aria-dropeffect,
aria-describedby), которые помогают вспомогательным
технологиям сообщать о возможности сброса.isDropTarget и isActive могут
использоваться для предоставления визуальных и текстовых подсказок.style={{
border: isDropTarget ? '2px solid green' : '2px dashed gray',
backgroundColor: isActive ? '#f0fff0' : isDropTarget ? '#ffffe0' : '#fff'
}}
useDrop поддерживает множественные типы элементов и
вложенные зоны. Например, можно создать иерархию зон, где родительская
зона принимает только контейнеры, а дочерняя – отдельные элементы. Для
этого используется проверка accepts и логика в
onDrop.
const {dropProps, isDropTarget} = useDrop({
onDrop: handleDrop,
accepts: ['container', 'item'],
onEnter: (item) => console.log('Наведение', item.type),
});
Такой подход позволяет строить гибкие интерфейсы с drag-and-drop, включая списки, сетки и сложные панели с поддержкой доступности.
useDrop обеспечивает мощный и гибкий способ работы с
зонами сброса в React Aria, позволяя создавать
безопасные, доступные и интуитивно понятные интерфейсы для
пользователей.