DropTarget์ ๋ง๋ค๊ณ ๋ค์๊ณผ ๊ฐ์ด getClientOffset์ ์ฐ๊ฒฐํ์ต๋๋ค.
targetCollect = function (connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
clientOffset: monitor.getClientOffset()
}
}
๊ทธ๋ฌ๋ ๊ตฌ์ฑ ์์ ๋ด์์ ๋๋๊ทธ๋ฅผ ์ด๋ํ ๋ ๋์์ ๋ง์ฐ์ค๋ฅผ ์์ง์ผ ๋๋ง๋ค ์ ๋ฐ์ดํธ ๋ ์ํ์ ์์ ํ์ง ์์ต๋๋ค (์ ๋ ฅ ๋ฐ ์ข ๋ฃ์์๋ง). ๊ทธ๋ฌ๋ ๋์ ์ฌ์์ hover _is_๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋ฉ๋๋ค. clientOffset prop์ด ๋ณ๊ฒฝ ๋ ๋๋ง๋ค ์ฃผ์ ๋์ง ์๋ ์ด์ ๊ฐ ์์ต๋๊น?
์ค, ์ข์ ์ง์ ์
๋๋ค. ๋ง์ต๋๋ค. ์ ๋์ด ์ฌ์ฉ๋ฒ์ ์์ํ์ง ๋ชปํ์ต๋๋ค. ํ์ฌ ํด๋ผ์ด์ธํธ ์คํ์
์ถ์ ์ ์ ํํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ DragLayer
์
๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฑ๋ฅ์์ ์ด์ ๋ก _drop ๋์ ์์ฒด _์ ๊ด๋ จ๋ ๊ฒ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง props๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
API ๋ฌธ์ ๋ผ๊ณ ๋งํ๊ณ ๋ช ๊ฐ์ง ํด๊ฒฐ์ฑ ์ด์์ ์ ์์ต๋๋ค.
getClientOffset()
๋ฐ collect
ํจ์ ๋ด์์ ์ ์ฌํ ๋ฉ์๋์ ์ ๊ทผํ๋ ๊ฒ์ ๊ธ์งํ๊ณ ๋์ DragLayer
๋ฅผ ์ฌ์ฉํ๋๋ก ์ง์ํ์ญ์์ค (์ฝ์ง๋ง ๋ฉ์ฒญํจ).๋๋ ๋ ๋ฒ์งธ ์ต์
์ํ๋ PR์ ๋ฐ์ ๋ค์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค. DragLayer
๊ตฌํ์ ํ์ธํ์ฌ ์คํ์
๋ณ๊ฒฝ์ ๊ตฌ๋
ํ๋ ๋ฐฉ๋ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ต์ ์ ์ดํด ๋ณด์์ง๋ง collect๊ฐ ํจ์์ด๋ฏ๋ก ๊น๋ค๋กญ๊ธฐ ๋๋ฌธ์ ์ด๋ค ๋ชจ๋ํฐ ํจ์๊ฐ ํธ์ถ ๋ ์ ์๋์ง ์์๋ด๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ์์น์ ์ค๋ ๋ ์์ ฏ์ ๋๋๊ทธํ์ฌ ์๋์ ์ผ๋ก ๋ณต์กํ ๋ฐฉ์์ผ๋ก ๋ค๋ฅธ ์์ ฏ์ ๋์ฒด ํ ์ ์์ต๋๋ค (Android์์ ํ๋ก๊ทธ๋จ ์์ด์ฝ์ ๋๋๊ทธํ๋ ๊ฒ์ ์๊ฐํด๋ณด์ญ์์ค). ๋๋๊ทธ ์์ฒด๋ HTML5 ์ค๋ ์ท์ผ๋ก ์๋ฒฝํ๊ฒ ๊ด์ฐฎ์ ๋ฐ๋ฉด, ์ ํํ ํธ๋ฒ ์์น์ ๋ฐ๋ผ ์์ฒด์ ์ผ๋ก ์ฌ์ ๋ ฌํด์ผํ๋ ๊ฒ์ ์ค์ ๋ก ๋์์ ๋๋ค. ๋์ ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋์ ์ฌ์์ ํธ๋ฒ๋ก ์ํ ํ ์ ์์ต๋๋ค. ๊ทธ๋์ ์ง๊ธ์ ์ด๊ฒ์๋๊ณ ํด๊ฒฐํ๊ฒ ์ต๋๋ค. ๋๋ผ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋๋ ์์ฃผ ๋ช ์๊ฐ์ ์ผ๋ก ๊ด์ฐฎ์ ์ผ์ํ๊ณ ์๋ค.
์ง๊ธ์ ์ด์ด ๋๊ฒ ์ต๋๋ค. # 172์ ๋์ผํฉ๋๋ค. canDrop
๋๋ ์์ง ๊ธฐ๋ฅ์์ ๋ธํ๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ ์์ํ์ง ๋ชปํ์ต๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ๋น์ฅ ๊ณ ์น์ง๋ ์๊ฒ ์ง ๋ง ํ ๋ฌ ์ ๋ ์ง๋๋ฉด ํด๊ฒฐ ๋ ๊ฒ์
๋๋ค.
๋๋ ๋ํ์ด ๋ฌธ์ ์ ๋ถ๋ช์ณค๋ค. ํด๋ผ์ด์ธํธ๊ฐ DropTarget ์ฌ์์ ํ๋๊ทธ๋ฅผ ์ ๋ฌํ์ฌ ์คํ์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ตฌ๋ ํ๋๋ก ํ์ฉํ๋ ๊ฒ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น? ์ฌ์ฉ์์๊ฒ๋ ๋ ํ๋์ "ํจ์ "์ด์ง๋ง ์คํ์ ์ ์๋์ผ๋ก ๊ตฌ๋ / ๊ตฌ๋ ์ทจ์ํ๋ ๊ฒ๋ณด๋ค ๊ฐ๋จํฉ๋๋ค.
RxJS-DOM์ ์ฌ์ฉํ์ฌ ์์์ ๋๋๊ทธ ์ค๋ฒ ์ด๋ฒคํธ๋ฅผ ๊ด์ฐฐํ๊ณ ๋ง์ฐ์ค ์ขํ๋ก ์ํ๋ฅผ ์ ๋ฐ์ดํธ ํ ์ ์์ต๋๊น? ์๋ง๋ Hacky ์๋ฃจ์ .
componentDidMount() {
this._events.dragOver = DOM.fromEvent(findDOMNode(this.refs.grid), 'dragover')
.throttle(200)
.subscribe(this.getMouseCoords)
}
๋๋ ๊ฒฐ๊ตญ ๋ชจ๋ํฐ๋ฅผ ์ก๊ณ DragLayer์ ๊ฐ์ ์คํ์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ตฌ๋ ํ์ต๋๋ค. ๋๋ ๋ํ ์ฅ์์์ ๋ด๋ถ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ๋๋๋ฆฌ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์์ต๋๋ค. ๋๋ ๋ด๊ฐํ๊ณ ์ถ์ ๊ฒ์ด _too_ ๋น์ ์์ ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ผ๋ฏ๋ก IMO๋ ๊ฐ๋จํ API ๋ณ๊ฒฝ์ผ๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค.
์ด๊ฒ์์ ๋์จ ๊ฒ์ด ์์ต๋๊น? ์ฌ์ฉ์ ์ ์ ๋๋๊ทธ ๋ ์ด์ด๊ฐ ์๋ DropTarget์์ ํธ๋ฒ ์์น์ ์ก์ธ์ค ํ ์์์ ๋ DropTarget์ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๋ ์ฝ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์ ์ ์ ๋๋๊ทธ ๋ ์ด์ด๊ฐ ์๋ DropTarget์์ ํด๋ผ์ด์ธํธ ์คํ์ ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ถ์ต๋๋ค.
+1 @jchristman์ดํ ๋ ค๋ ์ผ์ ์ ํํํ๊ณ ์ถ์ต๋๋ค.
+1. ์ด๊ฒ์ ๋ถ๋ช ํ๊ณ getClientOffset ()์ด canDrop ()์์ ์ ์๋ํ๋ ์ด์ ๋ฅผ ์ดํดํ๋ ค๊ณ ๋ง์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์์ต๋๋ค-๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋ฉ๋๋ค ...-๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๊ฐ์๋ ํญ๋ชฉ์ ๋ํ '์ด๋'์ ์ด๋ก ์ ๋ฌํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋๋ ๋จ์ง "์"๊ฐ ์๋๋ผ ํธ๋ฆฌ ๋ ธ๋์ ์์ ์๋์ ์ฝ์ ํ ์ ์์ด์ผํฉ๋๋ค. canDrop ()์ ๋ ธ๋๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ง์ "์ ํ"์ ๋๋กญ ์ค ์ด๋ค ๊ฒ์ ๊ตฌ์ฑ ์์์ ์ค์ ๋ก ์๋ ค์ ์ปจํธ๋กค์ด ๊ทธ์ ๋ฐ๋ผ ๋ค์ ํ์๋๋๋ก ํ ์์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. canDrop์์ ์ํ์ ๋ณ๊ฒฝํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋์ด์ ๋๊ธฐ ์์ ์ค์๋ onMouseMove ๊ตฌ๋ ์ด ์๋ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ง๊ธ๊น์ง ์์ฒญ๋ ์๊ฐ ๋ญ๋น์์ต๋๋ค ... ์ด๋ค ๋์์ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
@ibash , ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ ์์ ์ ๊ฒ์ ํด ์ฃผ์๊ฒ ์ต๋๊น?
ํธ๋ฒ ์ฌ์ฉ์ผ๋ก ์ ํํ๋ฉด ๋ง์นจ๋ด ๋์๊ฒ ๋์์ด๋์์ต๋๋ค.
`hover : (props : MyProps, ๋ชจ๋ํฐ : DropTargetMonitor, ๊ตฌ์ฑ ์์ : ReportItemRow) => {
if (๊ตฌ์ฑ ์์! = null) {
const clientOffset = monitor.getClientOffset ();
// Is the dragging node dragged above/below us as opposed to "on" us?
const elementRect = document.elementFromPoint(clientOffset.x, clientOffset.y).getBoundingClientRect();
const percentageY = (clientOffset.y - elementRect.top) / elementRect.height;
// Divide the box up into .25 .5 .25
const insertDragAndDropMagnetPercent = .25;
if (insertDragAndDropMagnetPercent >= percentageY) {
component.setState({ dropTarget: "above" });
}
else if (1 - insertDragAndDropMagnetPercent >= percentageY) {
component.setState({ dropTarget: "inside" });
}
else {
component.setState({ dropTarget: "below" });
}
}
},`
@ noah79 , ๊ทธ ๋์ ๋ฌด์ธ๊ฐ๊ฐ ์ฌ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์ฌ๋ฌ ๋๋กญ ํ๊ฒ์ ๋ง๋ค๊ณ ํธ๋ฆฌ ๋ ธ๋ ์๋์ ๋์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด :
_____| <-- drop div1 (above treenode1/below top of list)
treenode1_____| <-- drop div2 (on treenode1)
_____| <-- drop div3 (below treenode1/above treenode2)
treenode2_____| <-- drop div4 (on treenode 2)
_____| <-- drop div5 (below treenode2/above bottom of list)
๊ฒฐ๊ตญ 2n + 1 ๋๋กญ ๋์์ด๋ฉ๋๋ค. ์ฌ๊ธฐ์ n์ ๋ชฉ๋ก์ ์์ ์์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ ค ๋์ div์ ๋ฐ๋ผ ํธ๋ฆฌ ๋ชฉ๋ก์ ๋ชจ์์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ง๊ธ์ getClientOffset ()์ ์ก์ธ์ค ํ ์์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ด์ ๋งค์ฐ ์ ์ฌํ ์์ ์ ์ํํ์ง๋ง ์ฑ๋ฅ์ ์ํฅ์์ฃผ์ง ์์์ต๋๋ค. ๊ฐ ๋๋กญ div์ ๋์ด๋ treenode1 ๋ผ์ธ ๋์ด์ 1/2์ด์ด์ผํ๋ฉฐ ์ฒซ ๋ฒ์งธ ๋๋กญ div๋ ์ฒซ ๋ฒ์งธ ๋ผ์ธ๋ณด๋ค ๋์ treenode1 ๋ผ์ธ ๋์ด์ 1/4์ ์์นํด์ผํฉ๋๋ค. ์ฆ, CSS๋ ๋ค์๊ณผ ๊ฐ์์ผํฉ๋๋ค.
.dropdiv-container {
position: absolute;
top: -0.25em; /* If the top of this container is aligned with the top of the treenode list initially */
}
.dropdiv {
height: 0.5em; /* If the height of treenode1 line is 1em with no padding */
}
<div className='dropdiv-container'>
{ renderDropTargets(2 * listLength + 1) }
</div>
๋ง์ด ๋ผ?
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ ๋ฐฉ๋ฒ์ ์์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ํธ๋ฆญ์
react-dnd ๋ด๋ถ ๋ฐ ๊ธ๋ก๋ฒ ๋ชจ๋ํฐ๋ฅผ ์ง์ ์ฌ์ฉํ์ญ์์ค. ๋ณด์ธ์
DragDropMonitor.js ์์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ์๋์ ๋ํ ์์ด๋์ด๋ฅผ ์ป์ผ์ญ์์ค.
์ฐธ์กฐ : https://github.com/gaearon/dnd-core/blob/master/src/DragDropMonitor.js
๋น์ ์ ์ปคํผ ์คํฌ๋ฆฝํธ๋ฅผ ์ฉ์ํด์ผ ํ ๊ฒ์ ๋๋ค :)
# in the component being dragged, get access to the dragDropManager by adding
# it to the contextTypes
#
# dragDropManager is an instance of this:
# https://github.com/gaearon/dnd-core/blob/master/src/DragDropManager.js
<strong i="11">@contextTypes</strong>: {
dragDropManager: React.PropTypes.object
}
# because we can receive events after the component is unmounted, we need to
# keep track of whether the component is mounted manually.
#
# <strong i="12">@_monitor</strong> is what lets us access all the nice internal state - it is an instance of this:
# https://github.com/gaearon/dnd-core/blob/master/src/DragDropMonitor.js
componentWillMount: () =>
<strong i="13">@_isMounted</strong> = true
<strong i="14">@_monitor</strong> = @context.dragDropManager.getMonitor()
<strong i="15">@_unsubscribeToStateChange</strong> = @_monitor.subscribeToStateChange(@_onStateChange)
<strong i="16">@_unsubscribeToOffsetChange</strong> = @_monitor.subscribeToOffsetChange(@_onOffsetChange)
componentWillUnmount: () =>
<strong i="17">@_isMounted</strong> = false
<strong i="18">@_monitor</strong> = null
@_unsubscribeToStateChange()
@_unsubscribeToOffsetChange()
# we can access dragging / dropping state by accessing the monitor
_onStateChange: () =>
return unless <strong i="19">@_isMounted</strong>
# When we stop dragging reset the counter state and hide all cursors.
if <strong i="20">@_previousIsDragging</strong> && !@_monitor.isDragging()
console.log('no longer dragging')
<strong i="21">@_previousIsDragging</strong> = @_monitor.isDragging()
_onOffsetChange: () =>
return unless <strong i="22">@_isMounted</strong>
# mouse is the x/y coordinates
mouse = @_monitor.getClientOffset()
# item is the drag item
item = @_monitor.getItem()
# if you want to check if a dragged item is over a target, you need the
# targetId -- in the DropTarget wrapper you can pass it in like:
#
# (connect, monitor) ->
# {
# targetId: monitor.targetId,
# connectDropTarget: connect.dropTarget()
# }
#
# and then you can use it like below
@_monitor.isOverTarget(@props.targetId))
์ด๊ฒ ๋ง์ด ๋ผ? ๊ทธ๋ ์ง ์๋ค๋ฉด ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ถ๊ฐ ํ ์ ์์ต๋๋ค
๋๋ ๋ํ ์ค๋ ์ด๊ฒ์ ์คํํ๊ณ ๋ช ์๊ฐ์ ๋ญ๋นํ์ต๋๋ค. DropTarget-> The Collecting Function์ ๋ฌธ์์ ๋ฉ๋ชจ๋ฅผ ๋จ๊ธฐ๋ ๊ฒ์ ์ด๋ป์ต๋๊น? ๊ทธ๊ฒ์ ์ ์ด๋ ์ข์ ๊ฐ์ ์ํด ๋ค๋ฅธ ์ฌ๋๋ค์ ์๋ผ์ง ์์ ๊ฒ์ ๋๋ค.
Btw. ์ด ๋ฌธ์ ์ ๋ํ ๋ ๋ค๋ฅธ ์ถ์
ํ ํดํน์ dropTarget.hover()
์์ _as state_ ์ขํ๋ฅผ ๋ณด๋ด๋ ๊ฒ์
๋๋ค.
const dropTarget = {
hover(props, monitor, component) {
// HACK! Since there is an open bug in react-dnd, making it impossible
// to get the current client offset through the collect function as the
// user moves the mouse, we do this awful hack and set the state (!!)
// on the component from here outside the component.
component.setState({
currentDragOffset: monitor.getClientOffset(),
});
},
drop() { /* ... */ },
};
๋ฌผ๋ก setState์ ๋จ์ฉ์ ํผํ ์์๋ ๋ ์ ํํ ๋ฐฉ๋ฒ์ด ๋ง์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ์ด๋์ด ์์ ํดํน์ ๋งค์ฐ ์์ถ๋์ด ์์ผ๋ฉฐ์ด ๋ฌธ์ ๊ฐ ๊ฒฐ๊ตญ ํด๊ฒฐ ๋ ๋๊น์ง ์์ ์ ์ํ ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ๊ตฌ์ฑ ์์ ๋ฐ / ๋๋ ํ์ผ์ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ด๋ถ์ ์์กดํ์ง ์๊ณ ๋ฒ๊ทธ๋ฅผ ํดํน ํ ์ ์์ต๋๋ค.
ํธ์ง : ์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก noah79์ ๋์ผํฉ๋๋ค. ์ ๋ ์ง๊ธ๊น์ง ๊ทธ์ ์ฝ๋๋ฅผ ์ฝ์ง ์์์ต๋๋ค.
๋๋กญ์ ๋ง์ฐ์ค ์์น๋ฅผ ์ป์ ์์๋ ๋ฐฉ๋ฒ์ด ์ ๋ง ์์ต๋๊น? ๋ด ๋์ ๊ตฌ์ฑ ์์๋ ๊ทธ๊ฒ์ ๋ํด ์ ํ์๊ฐ ์์ผ๋ฏ๋ก setState
๋ ์ต์
์ด ์๋๋๋ค. redux ์์
์ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด ์ขํ๊ฐ ํ์ํฉ๋๋ค.
๋ด ๋ง์ง๋ง ๋ฉ์์ง๋ฅผ ๋ฌด์ํ์ญ์์ค. ์ด์ drop
๋ฐ endDrag
๊ฐ ์๋ก ๋ค๋ฅธ ๋ ๊ธฐ๋ฅ์ด๋ฉฐ drop
๋ด์์ ์ปค์ ์์น๋ฅผ ์ง์ ํ๋ ๊ฒ์ด ์์๋๋ก ์๋ํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค. :)
๋ด ํ ์คํธ์์ react-dnd๋ ํญ๋ชฉ์ด ๋์ ์๋ก ๋๋๊ทธ๋๋ ์ฆ์ ๋ง์ฐ์ค ์ด๋ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. html-backend๊ฐ์ด ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ฉด, ๋์ ์ปดํฌ๋ํธ๋ isOver ์์ฑ์ด true๋ก ์ค์ ๋ ๋ ์กฐ๊ฑด๋ถ๋ก ์ ์์ ์ธ mousemove ๋ฆฌ์ค๋๋ฅผ dom์ ๋ฐฐ์น ํ ์ ์์ต๋๋ค. ๊ทธ ํ์ด ์ฒญ์ทจ์๋ ๋ฌด์ธ๊ฐ๋ฅผ ๋๋๊ทธ ํ ๋ ์ ์์ ์ธ ๋ฐฉ์์ผ๋ก ๋ง์ฐ์ค ์์น๋ฅผ ์ ํํ ์ ์์ต๋๋ค. drag () ๋ฉ์๋์์ setState๋ฅผ ์ฌ์ฉํ์ฌ ์ผ์์ ์ผ๋ก ์๋ํ๋๋ก ์ค์ ํ์ต๋๋ค. react๋ ๋ ๋ ์ ํ ์ค๊ฐ์ ์ํ ์ค์ ์ ๋ํ ๊ฒฝ๊ณ ๋ฅผ ํ์ํฉ๋๋ค.
์ด๊ฒ๋ ์ ๋ฅผ ๋์ด ๋จ ๋ ธ์ต๋๋ค. API ์๋ฃจ์ ์ ๋ํ +1 ๋๋ ์ ์ด๋ FAQ์์๋ ํญ๋ชฉ.
์ด๋ฅผ ์ง์ํ ๊ณํ์ด ์์ต๋๊น?
ํดํน์๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ต๋๋ค. hover
๋ฅผ ๋ํํ๋ DropTarget
๋ํ ๋ํผ๋ฅผ ๋ง๋ค์ด ์์ง ํจ์์ ๋ํ ๋ค๋ฅธ ํธ์ถ์ ํธ๋ฆฌ๊ฑฐํ๊ณ ์์ง ํจ์๊ฐ ์ ๊ฐ์ ๋ฐํํ๋ฉด ๋ค์ ๋ ๋๋งํฉ๋๋ค. .
์ด ๋ฌธ์ ์ ๋ํด +1ํฉ๋๋ค. ์ฌ์ฉ ์ฌ๋ก๋ ์๋ก ๊ทผ์ ํ ์ฌ๋ฌ ๋๋กญ ๋์์ด ์๋ค๋ ๊ฒ์ ๋๋ค. ํธ๋ฒ๋ง ํ ๋ ์ ์ ํ ๋๋กญ ๋์์ด ๊ฐ์กฐ ํ์๋์ง๋ง ์ค์ ๋ก๋ ๋ง์ฐ์ค๋ฅผ ๊ฐ์ ธ๊ฐ ๋ฐฉํฅ์ ๋ฐ๋ผ ๋ฎ์ ๋์์ ๋๋กญ๋๋ ๊ฒ์ด ์ด์ํด ๋ณด์ ๋๋ค.
์คํ์
์ด ์
๋ฐ์ดํธ๋์ง ์๋ ์ด์ ๋ฅผ ์กฐ์ฌํ๋์ด ๋ฌธ์ ๋ฅผ ์ฐ์ฐํ ๋ฐ๊ฒฌํ๋๋ฐ, ์ฌ์ ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค.
๋๋ @ jedwards1211 ์ ์์ด๋์ด๋ฅผ DropTarget
์ ๊ฑฐ์ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์์ง๋ง, ์์ง ํจ์๋ฅผ ํตํด ์ฟผ๋ฆฌ ํ ์ํ ๋ชฉ๋ก ์ธ ์ต์
์์ collectRapidly
๋ฅผ ํ์ฉํ๊ณ ๋ชจ๋ ํธ๋ฒ ์ด๋ฒคํธ์ ๋ํด ์ ๋ฌํฉ๋๋ค. ์์ง ํจ์์์ ๋ชจ๋ ์ํ์ ๋ฌด์ฐจ๋ณ ์ ์ผ๋ก ์ ๋ฌํ๋ฉด ์ฝ๊ฐ์ ์ด์ ํจ์ด ๋ฐ์ํ๊ณ connect
๋ฅผ ์์ง ์์๊ฒ ์ ํ ์ ๋ฌํ ์ ์์ผ๋ฏ๋ก connectDropTarget
"๋น ๋ฅด๊ฒ"์ฟผ๋ฆฌํ์ง ์๋๋ก ๋ณดํธํด์ผํฉ๋๋ค.
๋ฐ๋ผ์ DropTarget(types, target, collect)
๋์ RapidFireDropTarget(types, target, collect, {collectRapidly: ['offset']})
. ์ฌ๊ธฐ์ offset
๋ ์๋ง๋ monitor.getOffset
ํจ์ ๊ณ์ด์์ ๊ฐ์๋ฐ๋ ๊ฒ์
๋๋ค.
import React from 'react';
import {DropTarget} from 'react-dnd';
import pick from 'lodash/pick';
function RapidFireDropTarget(types, spec, collect, options={}) {
let collectProps = {};
const prevHover = spec.hover;
const {collectRapidly = []} = options;
const dummyConnect = {
dropTarget: () => () => {
throw new Error('Rapidly collected props cannot include results from `connect`');
}
};
const WrappedComponent = Component => {
return class extends React.Component {
render() {
return <Component {...this.props} {...collectProps} />;
}
};
};
spec.hover = (props, monitor, component) => {
const allCollectProps = collect(dummyConnect, monitor);
collectProps = pick(allCollectProps, collectRapidly);
component.forceUpdate();
if (prevHover instanceof Function) {
prevHover(props, monitor, component);
}
}
return (Component) => {
return DropTarget(types, spec, collect, options)(WrappedComponent(Component));
};
}
export default RapidFireDropTarget;
์ด ๋ฌธ์ ๋ ์ต๊ทผ ํ๋์ด ์์๊ธฐ ๋๋ฌธ์ ์๋์ผ๋ก ์ค๋๋ ๊ฒ์ผ๋ก ํ์๋์์ต๋๋ค. ๋ ์ด์ ํ๋์ด ๋ฐ์ํ์ง ์์ผ๋ฉด ํ์๋ฉ๋๋ค. ๊ทํ์ ๊ธฐ์ฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
+1. ์ด๊ฒ์ ๋ถ๋ช ํ๊ณ getClientOffset ()์ด canDrop ()์์ ์ ์๋ํ๋ ์ด์ ๋ฅผ ์ดํดํ๋ ค๊ณ ๋ง์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์์ต๋๋ค-๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋ฉ๋๋ค ...-๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๊ฐ์๋ ํญ๋ชฉ์ ๋ํ '์ด๋'์ ์ด๋ก ์ ๋ฌํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋๋ ๋จ์ง "์"๊ฐ ์๋๋ผ ํธ๋ฆฌ ๋ ธ๋์ ์์ ์๋์ ์ฝ์ ํ ์ ์์ด์ผํฉ๋๋ค. canDrop ()์ ๋ ธ๋๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ง์ "์ ํ"์ ๋๋กญ ์ค ์ด๋ค ๊ฒ์ ๊ตฌ์ฑ ์์์ ์ค์ ๋ก ์๋ ค์ ์ปจํธ๋กค์ด ๊ทธ์ ๋ฐ๋ผ ๋ค์ ํ์๋๋๋ก ํ ์์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. canDrop์์ ์ํ์ ๋ณ๊ฒฝํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋์ด์ ๋๊ธฐ ์์ ์ค์๋ onMouseMove ๊ตฌ๋ ์ด ์๋ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ง๊ธ๊น์ง ์์ฒญ๋ ์๊ฐ ๋ญ๋น์์ต๋๋ค ... ์ด๋ค ๋์์ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
@ibash , ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ ์์ ์ ๊ฒ์ ํด ์ฃผ์๊ฒ ์ต๋๊น?