React-dnd: рд╣реБрдХ рдПрдкреАрдЖрдИ рдЪрд░реНрдЪрд╛

рдХреЛ рдирд┐рд░реНрдорд┐рдд 26 рдЕрдХреНрддреВре░ 2018  ┬╖  43рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: react-dnd/react-dnd

рдЖрдЦрд┐рд░рдХрд╛рд░ рдХреЛрдИ рдкреВрдЫрдиреЗ рд╡рд╛рд▓рд╛ рдерд╛! рдирдпрд╛ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрднрд╡рддрдГ рдпрд╣рд╛рдБ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдПрдкреАрдЖрдИ рдмрд╣реБрдд рдЬреНрдпрд╛рджрд╛ рдПрдХ рд╣реА рд░рд╣ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдЪрдУрд╕реА рд╕реАрдзреЗ рд╣реБрдХ рдореЗрдВ рдореИрдкрд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред

рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдо connectDragSource рдФрд░ connectDropTarget рдХреЛ рдХреЗрд╡рд▓ useRef рдХреЗ рдореВрд▓реНрдп рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд╛рдорд╛рди рдХреНрд▓реАрдирд░ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ!

design decisions discussion

рд╕рднреА 43 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд╣реБрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред рдЬреИрд╕реЗ рд╣реА рдкреНрд░рдХрд╛рд░ рдЕрд▓реНрдлрд╛ рдХреЗ рд▓рд┐рдП рдмреЗрдХ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рд╣рдо рдПрдХ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд╢рд╛рдЦрд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдореИрдВ рдПрдХ рд╢рд╛рдЦрд╛ рдореЗрдВ рдЪрд╛рд░реЛрдВ рдУрд░ рдЦреЗрд▓ рд░рд╣рд╛ рд╣реВрдВ: рдкреНрд░рдпреЛрдЧ / рд╣реБрдХ, рдмрд╕ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдПрдкреАрдЖрдИ рдХреИрд╕реЗ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИред рдмреЛрд░реНрдбрд╕рдХреНрд╡реЗрдпрд░ рдШрдЯрдХ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ:


const dropTarget = createDropTarget(ItemTypes.KNIGHT, {
    canDrop: (props: BoardSquareProps) => canMoveKnight(props.x, props.y),
    drop: (props: BoardSquareProps) => moveKnight(props.x, props.y),
})

const BoardSquare = ({ x, y, children }) => {
    const black = (x + y) % 2 === 1
    const [connectDropTarget, isOver, canDrop] = useDnd(
        dropTarget,
        connect => connect.dropTarget,
        (connect, monitor) => !!monitor.isOver,
        (connect, monitor) => !!monitor.canDrop,
    )

    return connectDropTarget(
        <div>
            <Square black={black}>{children}</Square>
            {isOver && !canDrop && <Overlay color={'red'} />}
            {!isOver && canDrop && <Overlay color={'yellow'} />}
            {isOver && canDrop && <Overlay color={'green'} />}
        </div>,
    )
}

рддреЛ рдпрд╣рд╛рдБ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ createDropTarget рдЦреАрдВрдЪреЗрдВ / рдбреНрд░реЙрдк рдЖрдЗрдЯрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рддрд╛рд░реНрдХрд┐рдХ рдЬреНрдЮрд╛рди рдХреЛ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЖрдИрдбреА рдФрд░ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рд╣реИ, рдФрд░ useDnd рд╣реБрдХ рдЗрд╕реЗ DnD рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╡рд╛рдпрд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдкреНрд░реЙрдкрд░ рдЗрдХрдЯреНрдард╛ рдХрд░реЗрдЧрд╛ред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдХреЛ рд╕реНрдХреЗрдЪ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реИ

@darthtrevino рдЖрдк рдХрд┐рд╕ рд╢рд╛рдЦрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ? рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдБ рдХрд┐ рдХреНрдпрд╛ рд╣рдо Refs рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ connectDropTarget рдПрдХ рд╕рд╛рде рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рдпрд╣ рджреЗрдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдЗрд╕реЗ рдЖрдкрдХреА рд╢рд╛рдЦрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рд╡рд╛ рд╕рдХрддрд╛ рд╣реВрдБ!

const dropTarget = createDropTarget(ItemTypes.KNIGHT, {
    canDrop: (props: BoardSquareProps) => canMoveKnight(props.x, props.y),
    drop: (props: BoardSquareProps) => moveKnight(props.x, props.y),
})

const BoardSquare = ({ x, y, children }) => {
    const dropTargetElement = useRef(null);
    const black = (x + y) % 2 === 1
    const [isOver, canDrop] = useDnd(
        dropTargetElement,
        dropTarget,
        ...
    )

    return (
        <div ref={dropTargetElement}>
            <Square black={black}>{children}</Square>
            {isOver && !canDrop && <Overlay color={'red'} />}
            {!isOver && canDrop && <Overlay color={'yellow'} />}
            {isOver && canDrop && <Overlay color={'green'} />}
        </div>
    )
}

@ jacobp100 рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рд╕рдорд╛рди рд╣реБрдХ-рдЖрдзрд╛рд░рд┐рдд рдПрдкреАрдЖрдИ рдкреНрд░рддреАрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рд░реЗрдлрд░реА рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣реБрдХ рджреНрд╡рд╛рд░рд╛ рд╣реА рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬреИрд╕реЗ const [isOver, canDrop, ref] = useDnd(...) ), рдЗрд╕рдХреЗ рдЬреЗрдПрд╕рдПрдХреНрд╕ рдЯреНрд░реА рдореЗрдВ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП)

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрдИ рд╣реБрдХ рдореЗрдВ рд░реЗрдл рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдард┐рди рдмрдирд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рдЬреЛ рдПрдХ рд╣реА рд░реЗрдлрд░реА рдореЗрдВ рдХрдИ рд░реЗрдл рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИред рдпрд╣ рдХреМрди рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдереА?

рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЗрд╕ рдкрд░ рд╕рдореНрдореЗрд▓рди рдХреНрдпрд╛ рд╣реИ!

рдпрд╣ рдХрдИ рд╣реБрдХ рдореЗрдВ рд░реЗрдл рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдард┐рди рдмрдирд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рдЬреЛ рдПрдХ рд╣реА рд░реЗрдлрд░реА рдореЗрдВ рдХрдИ рд░реЗрдл рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИред

рд╕рдЪ, рдФрд░ рд╕рдЪ :-)

рдпрд╣ рдХреМрди рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдереА?

рд▓рдЧрддрд╛ рд╣реИ рдпрд╣ рдлрд┐рд░ рд╕реЗ рдПрдЯреАрдПрдо рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛: - / - рдкрд┐рдЫрд▓реЗ рдПрдХ рдкрдЦрд╡рд╛рдбрд╝реЗ рдореЗрдВ рд╣реБрдХ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреНрд░рдпреЛрдЧ ...

Https://github.com/beizhedenglong/react-hooks-lib рдЬреЛ рдХрд░рддрд╛ рд╣реИ
const { hovered, bind } = useHover(); return <div {...bind}>{hovered ? 'yes' : 'no'}</div>;
рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ bind рдорддрд▓рдм рдПрдХ рд░реЗрдлрд░реА рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ?
[рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдирд╣реАрдВ, рдпрд╣ рд╕рд┐рд░реНрдл { onMouseEnter, onMouseLeave } , рдмрд┐рд▓реНрдХреБрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ ...]

рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐ рдХреБрдЫ рдЕрдиреНрдп рдПрдкреАрдЖрдИ рд╣реБрдХ рд╕реЗ рд╕реАрдзреЗ рд░реЗрдлрд░реА рдХреЛ рд▓реМрдЯрддреЗ рд╣реБрдП рджреЗрдЦрддреЗ рд╣реИрдВред

рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣ рдлрд┐рд▓рд╣рд╛рд▓ рдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЬрд┐рд╕ рд╢рд╛рдЦрд╛ рдореЗрдВ рд╣реВрдВ, рд╡рд╣ experiment/hooks

рдмрд╕ рдпрд╣рд╛рдБ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐:

const dropTarget = createDropTarget(ItemTypes.KNIGHT, {
    canDrop: props => canMoveKnight(props.x, props.y),
    drop: props => moveKnight(props.x, props.y),
})

const BoardSquare = ({ x, y, children }) => {
    const black = (x + y) % 2 === 1
        const ref = useRef(null)
    const [isOver, canDrop] = useDnd(
        connect => connect(ref, dropTarget),
        monitor => monitor.isOver,
        monitor => monitor.canDrop,
    )

    return (
        <div ref={ref}>
            <Square black={black}>{children}</Square>
            {isOver && !canDrop && <Overlay color={'red'} />}
            {!isOver && canDrop && <Overlay color={'yellow'} />}
            {isOver && canDrop && <Overlay color={'green'} />}
        </div>,
    )
}

рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рдбреНрд░реИрдЧрд╕реЛрд░реНрд╕ рдФрд░ рдбреНрд░реЙрдкрдЯрд╛рд░реНрдЧ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрджрд┐ рд╣рдо рд░реЗрдл рдХреЛ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмрд╛рдХреА рддрд░реНрдХ рдЗрд╕реЗ рдХрдИ dnd рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

const dropTarget = createDropTarget(ItemTypes.CARD, {
    canDrop: () => false
    hover(props, monitor) {
        /**/
    },
})
const dragSource = createDragSource(ItemTypes.CARD, {
    beginDrag: props => /*...*/,
    endDrag: (props, monitor) => /*...*/
})

function Card({ text }) {
    const ref = useRef(null)
    const [isDragging] = useDnd(
        connect => connect(ref, dropTarget, dragSource),
        monitor => monitor.isDragging,
    )
    const opacity = isDragging ? 0 : 1

    return (
        <div ref={ref} style={{ ...style, opacity }}>
            {text}
        </div>
    )
}

рддреЛ useDnd рдЬреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛


export type DndConcept = DragSource | DropTarget
export type ConnectorFunction = (connector: Connector /*new type*/) => void
export type CollectorFunction<T> = (monitor: DragDropMonitor) => T

export function useDnd(
    connector: ConnectorFunction,
    ...collectors: CollectorFunction[]
): any[] {
    const dragDropManager = useDragDropManager()
        // magic
       return collectedProperties
}

export function useDragDropManager(): DragDropManager {
    return useContext(DragDropContextType)
}

рдкрд╛рдЧрд▓ рд╡рд┐рдЪрд╛рд░, рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо connect рдФрд░ monitor рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рд╣реБрдП?

const Test = props => {
  const ref = useRef(null);
  const { isDragging } = useDragSource(ref, ItemTypes.CARD, {
    canDrag: props.enabled,
    beginDrag: () => ({ id: props.id }),
  });

  return <div ref={ref} style={{ color: isDragging ? 'red' : 'black' }} />
}

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрдиреЗрдХреНрдЯ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдореЙрдирд┐рдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреНрд░реЙрд╕реНрдкреЗрдХреНрдЯ рдорд┐рд▓рддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рдЖрдИрдбреНрд░реИрдЧрд┐рдВрдЧ

рддреЛ рд╢рд╛рдпрдж useDragSource(ref, <type>, <spec>, <collect>) ред рдпрд╣ рдмрд╣реБрдд рд╕рд╛рд░реЗ рддрд░реНрдХ рд╣реИрдВ, рдФрд░ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рджреЛ рдореЛрдЯреА рд╡рд╕реНрддреБрдПрдВ рд╣реЛрдирд╛ рдЕрдЬреАрдм рд╣реЛ рд╕рдХрддрд╛ рд╣реИ

рдХреНрдпрд╛ рд╣рдо рдЕрднреА рдореЙрдирд┐рдЯрд░ рд╕реЗ рд╕рднреА рд╕рд╣рд╛рд░рд╛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдкрд░реЗрд╢рд╛рдиреА рд╣реЛрдЧреА: https://github.com/react-dnd/react-dnd/blob/84db06edcb94ab3db37e8fe89fcn55b1ad07ce/packages/react/drc/src/interfaces.ts#117

IIRC, DragSourceMonitor, DropTragetMonitor, рдФрд░ DragLayerMonitor рд╕рднреА рдХреЛ DragDropMonitor рд╡рд░реНрдЧ рдореЗрдВ рдиреАрдЪреЗ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдо рдЯрдХрд░рд╛рд╡ рдХреЗ рдирд╛рдордХрд░рдг рдореЗрдВ рднрд╛рдЧ рд▓реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХреА рджреЛрд╣рд░реА рдЬрд╛рдВрдЪ рдХрд░реВрдВрдЧрд╛ред

@yched рд╕рд┐рд░реНрдл рдЗрд╕ рдФрд░ рд╣реБрдХ рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рд░рд╣рд╛ рд╣реИ рдФрд░ рд╣рдордиреЗ рджреЗрдЦрд╛ рдХрд┐ рд╣рдореЗрдВ рд░реЗрдлрд░реА рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИред рдорд╛рдорд▓рд╛ рджреЗрдЦреЗрдВ рдЬрдм рдХреЛрдИ рд╕реНрд░реЛрдд рдФрд░ рд▓рдХреНрд╖реНрдп рджреЛрдиреЛрдВ рд╣реЛред

const Test = () => {
  const ref = useRef(null)
  const source = useDragSource(ref, тАжprops)
  const target = useDragTarget(ref, тАжprops)

  return <div ref={ref}>тАж</div>
}

@ jacobp100 рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

рдареАрдХ рд╣реИ, рд╡рд┐рдЪрд╛рд░,

const Test = (props) => {
  const ref = useRef(null)
  const sourceMonitor = useDragSource(ref, 'item' {
    beginDrag: () => ({ id: props.id })
  })
  const targetMonitor = useDropTarget(ref, ['item'] {
    drop: () => alert(targetMonitor.getItem().id)
  })
  const { isDragging } = useMonitorSubscription(targetMonitor, () => ({
    isDragging: targetMonitor.isDragging()
  })

  return <div ref={ref}>тАж</div>
}

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдбреНрд░реИрдЧ рд╕реЛрд░реНрд╕ рдФрд░ рдЯрд╛рд░рдЧреЗрдЯ рдХреЗ рд▓рд┐рдП рдЪрд╢реНрдорд╛ рдХрд┐рд╕реА рднреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд╣реБрдВрдЪ рд╣реИ

useMonitorSubscription рдЕрдкрдбреЗрдЯ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдПрдХ рдЙрдерд▓реЗ рдХреЗ рдмрд░рд╛рдмрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд░реВрдк рд▓рд┐рдпрд╛

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ useDragSource(ref, <type>, <spec>, <collect>) рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд╡рд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд▓рд╛рддрд╛ рд╣реИред рдлрд░реНрдХ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рдЖрдк рдПрдХ рд╣реЙрдХ рд╕реЗ рд╣реБрдХ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рджреЛ рдореЛрдЯреА рд╡рд╕реНрддреБрдПрдВ рд╣реЛрдирд╛ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдмрд╣реБрдд рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рднреА рдРрд╕рд╛ рдХрд░рдирд╛ рдерд╛:

const DragDrop = () => {
  const ref = useRef(null);

  const dragSource = {
    beginDrag() {
      return props;
    }
  };

  const collectSource = monitor => {
    return {
      isDragging: monitor.isDragging()
    };
  };

  const { isDragging } = useDragSource(ref, "Item", dragSource, collectSource);

  const dropTarget = {
    drop() {
      return undefined;
    }
  };

  const collectTarget = monitor => {
    return {
      isOver: monitor.isOver()
    };
  };

  const { isOver } = useDropTarget(ref, "Item", dropTarget, collectTarget);

  return <div ref={ref}>Drag me</div>;
};

рдЕрдЪреНрдЫреА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдЕрдиреНрдп рд╣реБрдХ рд╕реЗ рднреА рдорд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

const Drag = () => {
  const ref = useRef(null);
  const context = useContext(Context)

  const dragSource = {
    beginDrag() {
      context.setDragItem(props)
      return props;
    },
    endDrag() {
      context.setDragItem(null)
    }
  };

  const collectSource = monitor => {
    return {
      isDragging: monitor.isDragging()
    };
  };

  const { isDragging } = useDragSource(ref, "Item", dragSource, collectSource);

  return <div ref={ref}>Drag me</div>;
};

рдПрдХ рдЕрдЪреНрдЫрд╛ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдкреНрд░реЙрдкреНрд╕ рдФрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЛ рддрд░реНрдХреЛрдВ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдиреНрдп рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рджрд╛рдпрд░реЗ рдореЗрдВ рдЙрдирдХреА рдкрд╣реБрдВрдЪ рд╣реИред

^ рдореИрдВрдиреЗ рдЕрдкрдиреА рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА рдХреЛ рдХреЗрд╡рд▓ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ collectSource рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдореЙрдирд┐рдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ - рдЖрдк рдмрд╕ рджрд╛рдпрд░реЗ рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ

@ рдЬреИрдХреЛрдмрдк 100 рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВред рдореЗрд░реЗ рд▓рд┐рдП, рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╣рдореЗрдВ рдореЙрдирд┐рдЯрд░ рд╕реЗ рдбреЗрдЯрд╛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рд╣реБрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдпрджрд┐ рд╣рдо рдЗрд╕реЗ рдпреВрдЬрдбреНрд░рд╛рдЧреНрд░рд╕ рд╕реЛрд░реНрд╕ рдФрд░ рдпреВрдЬрд╝рдбреНрд░реЙрдкрдЯрд╛рд░реНрдЧ рдореЗрдВ рднреА рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рддрдм рд╕рдордЭ рдореЗрдВ рдЖрдпрд╛ рдЬрдм рд╕рд╛рдорд╛рди рдПрдЪрдУрд╕реА рдерд╛, рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдХрдиреЗрдХреНрдЯ рд╕рд╛рдорд╛рди рдХреЛ рд╡реИрд╕реЗ рднреА рд▓рд┐рдВрдХ рдХрд░рдирд╛ рдерд╛ред

рд▓реЗрдХрд┐рди рдЕрдм рдЙрдиреНрд╣реЗрдВ рдпреБрдЧрд▓ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рддрдХрдиреАрдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ред

рддрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдЙрдирдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ рд╣реИ - рд╢рд╛рдпрдж рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд▓ рдШрдЯрдХреЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдЙрд╕ рдШрдЯрдХ рдХреЛ рдирд╣реАрдВ рдЬреЛ рдШрд╕реАрдЯрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдмреЛрдирд╕ рднреА рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдореЙрдирд┐рдЯрд░ рд╕рджрд╕реНрдпрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╣реБрдХ рдХреЛ рд╣рд┐рд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЙрд╕ рдиреЗ рдХрд╣рд╛, рдпрд╣ рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдорд╕реМрджрд╛ рд╣реИ! рдореИрдВ рдЗрд╕реЗ рдмрджрд▓рдиреЗ рдХрд╛ рд╡рд┐рд░реЛрдз рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ рдЕрдЧрд░ рдпрд╣ рдЖрдо рд╕рд╣рдорддрд┐ рд╣реИ!

рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реНрдХ рд╣реИред рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдПрдХ рдФрд░ рдПрдХрдорд╛рддреНрд░ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рднреНрд░рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рд╡реЗ рдореЙрдирд┐рдЯрд░ рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрд╢реНрдЪрд░реНрдп рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:

const Test = (props) => {
  const ref = useRef(null)

  const sourceMonitor = useDragSource(ref, 'item', {
    beginDrag: () => ({ id: props.id })
  })

  const targetMonitor = useDropTarget(ref, ['item'], {
    drop: () => alert(targetMonitor.getItem().id)
  })

  const { isDragging } = useMonitor(targetMonitor, () => ({
    isDragging: targetMonitor.isDragging()
  })

  return <div ref={ref}>{sourceMonitor.isDragging() ? 'Dragging' : 'Drag me'}</div>
}

рд╕рдВрднрд╡рддрдГ рдЬрдм рдЖрдк useMonitor рд╣реБрдХ рдХреЗ рдмрд╛рд╣рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдФрд░ рдЪреЗрддрд╛рд╡рдирд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛! рдпрд╣ рдЙрди рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬрд┐рди рдкрд░ рдореИрдВ 100% рдЙрддреНрд╕реБрдХ рдирд╣реАрдВ рд╣реВрдВ: useMonitor рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд░рд┐рдПрдХреНрдЯ рдХреЛрд░ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рд╣реБрдХ рдХреЗ рдЦрд┐рд▓рд╛рдл рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рд╢рд╛рдпрдж рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреБрдЫ рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ,

const Test = (props) => {
  ...
  useMonitorUpdates(targetMonitor, () => [targetMonitor.isDragging()]);

  return <div ref={ref}>{sourceMonitor.isDragging() ? 'Dragging' : 'Drag me'}</div>
}

рдмреЗрд╢рдХ, рдЗрд╕ рдлрд╝реЙрд░реНрдо рдХреЗ рд╕рд╛рде рдмрдЧреЛрдВ рдХреЛ рдкреЗрд╢ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ

рдореИрдВ рд░рд┐рдПрдХреНрд╢рди-рдбреАрдПрдирдбреА рдЗрдВрдЯрд░реНрд▓реНрд╕ рдХрд╛ 100% рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╡рд╣рд╛рдВ рдореЙрдирд┐рдЯрд░ рдирд╣реАрдВ рд╣реИ рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЖрдкрдХреЗ рдорд╛рдЙрд╕ рдХреЗ рдореВрд╡реНрд╕ рдХреЛ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ?

рддреЛ рдкрд┐рдЫрд▓реЗ рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ рдпрджрд┐ рдЖрдк рдЙрдкрдпреЛрдЧ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВрдореЙрдирд┐рдЯрд░рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдФрд░ рдХреЗрд╡рд▓ monitor.isDragging() рд░реЗрдВрдбрд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣реИ?

рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛?

const Test = (props) => {
  const ref = useRef(null)

  const sourceMonitor = useDragSource(ref, 'item', {
    beginDrag: () => ({ id: props.id })
  })

  return <div ref={ref}>{sourceMonitor.isDragging() ? 'Dragging' : 'Drag me'}</div>
}

рдореЙрдиреАрдЯрд░ рдореЗрдВ subscribe рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ рдЕрдкрдиреЗ рд╢реНрд░реЛрддрд╛рдУрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрдм рднреА рдХреЛрдИ рдореВрд▓реНрдп рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ _something_ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдШрдЯрдХ рдХреЛ рдкрддрд╛ рд╣реЛ рдХрд┐ рдХрдм рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рд╣реИред

рдкрд┐рдЫрд▓реА рдкреЛрд╕реНрдЯ рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реБрдП, рдпрджрд┐ рд╣рдо рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЙрддрдирд╛ рд╣реА рд╕рд░рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ,

const Test = (props) => {
  ...
  useMonitorUpdates(sourceMonitor);

  return <div ref={ref}>{sourceMonitor.isDragging() ? 'Dragging' : 'Drag me'}</div>
}

рдПрдХ рджреЛ рд╡рд┐рдЪрд╛рд░ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдХреНрдпрд╛ рд╣рдо ref рддрд░реНрдХ рдХреЛ Ref рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

const dragSource = useDragSource('item', spec);
return <div ref={dragSource}/>

// or if you want to use a ref
const ref = useRef();
const dragSource = useDragSource('item', dragSourceSpec)(ref); 
const dropTarget = useDropTarget('item', dropTargetSpec)(ref); 

рджреВрд╕рд░рд╛, рдЙрдиреНрд╣реЗрдВ useMonitorUpdates рдореЗрдВ рдПрдХ рдФрд░ рд╣реБрдХ рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рд╕рд┐рд░реНрдл рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

const dragSource = useDragSource('item', spec);

const { isDragging } = dragSource.subscribe(() => ({
  isDragging: targetMonitor.isDragging()
}));

рдореИрдВ рдЗрд╕реЗ рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрдВрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдЙрдореНрдореАрджрд╡рд╛рд░ рдПрдкреАрдЖрдИ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдирдП рдореБрджреНрджреЛрдВ рдХреЗ рд╕рд╛рде рдЙрд╕ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред рдзрдиреНрдпрд╡рд╛рдж!

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣реБрдХ рдПрдкреАрдЖрдИ рдХреЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдореЗрдВ рджреЛрд╖ рд╣реИ: https://github.com/Swizec/useDimensions/ues_3

рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдХрдиреЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХреНрд▓рд╛рд╕-рдЖрдзрд╛рд░рд┐рдд рдПрдкреАрдЖрдИ рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ:


const Box = ({ name }) => {
    const [{ isDragging }, dragSource] = useDrag({
        item: { name, type: ItemTypes.BOX },
        end: (dropResult?: { name: string }) => {
            if (dropResult) {
                alert(`You dropped ${item.name} into ${dropResult.name}!`)
            }
        },
        collect: monitor => ({
            isDragging: monitor.isDragging(),
        }),
    })
    const opacity = isDragging ? 0.4 : 1

    return (
        <div ref={node => dragSource(node)} style={{ ...style, opacity }}>
            {name}
        </div>
    )
}

рддреЛ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдПрдкреАрдЖрдИ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ ...

const [props, connectDragSource, connectDragPreview] = useDrag(spec)
const [props, connectDropTarget] = useDrop(spec)

рдореИрдВ рдХрдиреЗрдХреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рджреВрд░ рдЬрд╛рдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдПрдкреАрдЖрдИ рдЙрдирдХреЗ рдмрд┐рдирд╛ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИ, рддреЛ рд╣рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдЙрд╕ рдореБрджреНрджреЗ рдХреЛ рдкрдврд╝рд╛ рд╣реИ - рд╣рдорд╛рд░реЗ API рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ DOM рдиреЛрдб рдХрд╛ рдорд╛рдк рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЖрдЙрдЯ рдкреНрд░рднрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдБ рд▓реЗрдЖрдЙрдЯ рдЗрдлреЗрдХреНрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдмрд╕ dnd-core рдХреЗ рд╕рд╛рде DOM рдиреЛрдбреНрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

@gaearon , рд╣рдорд╛рд░реЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реБрдХ API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреАрдЖрдИ рдХреЗ рд╕рдорд╛рди рд╣реИ - рдХреНрдпрд╛ рд╡рд╣ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░реВрдк рдПрдХ рдПрдВрдЯреАрдкреИрд░реНрдЯрди рд╣реИ (рдЬреИрд╕реЗ let [props, ref] = useCustomHook(config) ), рдпрд╛ рдХреНрдпрд╛ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЙрд╕ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдЬрд┐рд╕реЗ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реА рд╣реИ?

@darthtrevino рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдЧрд░ рдЖрдк рдпреВрдЬрдбреНрд░реЗрдб рд╕реЛрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдк рд░реЗрдлрд░реА рдХреЛ рдПрдХ рдЪрд╛рдЗрд▓реНрдб рдХрдВрдкреЛрдиреЗрдВрдЯ рдФрд░ рдЪрд╛рдЗрд▓реНрдб рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЗ рд░реЗрдВрдбрд░рд░реНрд╕ рдХреЗ рдкрд╛рд╕ рднреЗрдЬрддреЗ рд╣реИрдВ рддреЛ рд╣рдо dnd-core рдореЗрдВ рд░рдЬрд┐рд╕реНрдЯрд░реНрдб рдбреЛрдо рдиреЛрдб рдХреЛ рдЕрдкрдбреЗрдЯ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ:

function Parent() {
  const ref = useRef();
  const dragSource = useDragSource(ref, ...);

  return <Child connect={ref} />;
}

function Child({ connect }) {
  const [open, setOpen] = useState(false);

  function toggle() {
    setOpen(!open);
  }

  return (
    <Fragment>
      <button onClick={toggle}>Toggle</button>
      {open ? <div ref={connect} /> : null}
    </Fragment>
  );
}

Yechред рдореИрдВ рджреЗрдЦреВрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдЗрд╕ рд╣рдлреНрддреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╣рдлреНрддреЗ рдХреЗ рдмрд╛рдж рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдпрд╛ рдирд╣реАрдВ рдпрд╣ рд╕рд╛рдмрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд╡рд┐рд╕реНрдлреЛрдЯ рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ

рдпрджрд┐ рдпрд╣ рдКрдкрд░ рдЙрдарддрд╛ рд╣реИ, рддреЛ рдХрдиреЗрдХреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрдордмреИрдХ рд╣реЛрдЧрд╛

рдЕрдЧрд░ рдореИрдВрдиреЗ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рддреЛ рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдБ рдкреБрди: рдкреЗрд╢ рдХрд░ рдкрд╛рдпрд╛: https://codesandbox.io/s/xj7k9x4v4

рдХрдмреВрдо , рдЕрдЪреНрдЫрд╛ рдХрд╛рдо, рдзрдиреНрдпрд╡рд╛рдж

рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдХрд▓ рд░рд╛рдд рдХрд╛ рдПрдХ рд╕рдордп рдмрд┐рддрд╛рдпрд╛ рд╣реИ рдЬреЛ рд╣реБрдХ рдПрдкреАрдЖрдИ рдХреЛ рдХрдиреЗрдХреНрдЯрд░ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдПрдкреАрдЖрдИ рдбрд┐рдЬрд╛рдЗрди рдХреА рдмрд╛рдд рд╣реИ, рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ рдирдлрд░рдд рдХрд░рддрд╛ рд╣реВрдВред

рдореЗрд░рд╛ рдЕрдЧрд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рд░реЗрдл-рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдмрдЬрд╛рдп рдХреЙрд▓рдмреИрдХ-рд░реЗрдл рд▓реМрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╣рдореЗрдВ рдПрдХ рд░реЗрдлрд░реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдпрд╛ рдЗрд╕рдореЗрдВ рдПрдХ рд░реЗрдл рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЪреАрд▓рд╛рдкрди рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:

let [props, dragSource] = useDrag({spec}) // dragSource result is a function
return <div ref={dragSource} {...props}>hey</div>

рдЪреЗрдирд┐рдВрдЧ

let [dragProps, dragSource] = useDrag({spec})
let [dropProps, dropTarget] = useDrag({spec})

return <div ref={node => dragSource(dropTarget(node))}>hey</div>

рд░реЗрдлрд░реА рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде

let ref = useRef(null)
let [dragProps, dragSource] = useDrag({spec})
let [dropProps, dropTarget] = useDrag({spec})
dragSource(dropTarget(ref))

return <div ref={ref}>hey</div>

рдореЗрд░реЗ рд▓рд┐рдП, рдпрд╣ useLayoutEffect рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ рдЕрдЧрд░ рдШрдЯрдХ рдпрд╛ рдЙрд╕рдХреЗ рдХрд┐рд╕реА рднреА рдмрдЪреНрдЪреЗ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдЧрд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдореИрдВрдиреЗ рд░рд┐рдПрдХреНрд╢рди рд░реЗрдкреЛ рдореЗрдВ рдЯрд┐рдХрдЯ рдмрдирд╛рдпрд╛ рд╣реИ ред рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред

let [dragProps, dragSource] = useDrag({spec})
let [dropProps, dropTarget] = useDrag({spec})

return <div ref={node => dragSource(dropTarget(node))}>hey</div>

рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХрд┐рддрдирд╛ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рд░реЗрдлрд░реА рдХреЛ рд╣рд░ рдПрдХ рд░реЗрдВрдбрд░ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдПрдВрдЧреЗред рддреЛ рд╣рд░ рд░реЗрдВрдбрд░ рдХреЗ рд╕рд╛рде, рдЖрдкрдХреЛ рдХрдиреЗрдХреНрдЯ рдФрд░ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдРрд╕рд╛ рд╣реЛрдирд╛ рдмреЗрд╣рддрд░ рдирд╣реАрдВ рд╣реЛрдЧрд╛

node => {
    dragSource(node)
    dropTarget(node)
}

рдпрд╣ рдПрдХ рд╣реА рдмрд╛рдд рд╣реЛрдЧреА

рдЗрд╕рд▓рд┐рдП, рдореЗрд░реА рдкрд╣рд▓реЗ рдХреА рдЯрд┐рдкреНрдкрдгреА рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, # 1280 рдореЗрдВ рдПрдкреАрдЖрдИ рдореБрдЭреЗ рдкрд╣рд▓реЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдХрд╛рд░ рджреЗ рд░рд╣рд╛ рд╣реИред рдпрд╣рд╛рдБ рдпрд╛ рд╡рд╣рд╛рдБ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

dreamcog picture dreamcog  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Okami92 picture Okami92  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

BrennanRoberts picture BrennanRoberts  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rubayethossain picture rubayethossain  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

croraf picture croraf  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ