react-dnd
Version:
Drag and Drop for React
34 lines (33 loc) • 1.39 kB
JavaScript
import { useRef, useMemo, useLayoutEffect } from 'react';
import invariant from 'invariant';
import { useMonitorOutput } from './internal/useMonitorOutput';
import { useDragSourceMonitor, useDragHandler } from './internal/drag';
/**
* useDragSource hook
* @param sourceSpec The drag source specification *
*/
export function useDrag(spec) {
const specRef = useRef(spec);
specRef.current = spec;
// TODO: wire options into createSourceConnector
invariant(spec.item != null, 'item must be defined');
invariant(spec.item.type != null, 'item type must be defined');
const [monitor, connector] = useDragSourceMonitor();
useDragHandler(specRef, monitor, connector);
const result = useMonitorOutput(monitor, specRef.current.collect || (() => ({})), () => connector.reconnect());
const connectDragSource = useMemo(() => connector.hooks.dragSource(), [
connector,
]);
const connectDragPreview = useMemo(() => connector.hooks.dragPreview(), [
connector,
]);
useLayoutEffect(() => {
connector.dragSourceOptions = specRef.current.options || null;
connector.reconnect();
}, [connector]);
useLayoutEffect(() => {
connector.dragPreviewOptions = specRef.current.previewOptions || null;
connector.reconnect();
}, [connector]);
return [result, connectDragSource, connectDragPreview];
}