Drag and drop 사용법 - boostcamp-2020/Project15-A-Client-Based-Formula-Editor GitHub Wiki
React DnD
- Drag and Drop for React
- 공식문서 바로가기
1. 설치
npm install react-dnd
npm install react-dnd-html5-backend
2. 특징
- 내부적으로 Redux를 사용
- HTML5 drag and drop API 위에 구축 되어 있음
- HTML5 drag and drop backend는 DOM 이벤트를 React DnD가 처리 할 수 있는 내부 Redux 작업으로 변환한다.
- 터치 스크린에서는 동작하지 않기 때문에, 터치 이벤트를 사용하려면 HTML5 drag and drop backend 사용하지 않고, 구현해서 작성해야한다.
- IE 지원하지 않는다.
- 드래그 된 DOM 노드를 스크린 샷하고, 드래그 미리보기를 지원한다. (따라서 커서를 움직일 때, 그림을 그릴 필요가 없다는 것이 편리하다)
3. 사용 방법
useDrag
: 드래그 할 컴포넌트에서 사용한다.
const [{ isDragging }, drag] = useDrag({
item: { name, type: 'box', latex, isPossible },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
return (
<>
<StyleComponent.InputLatexContent
ref={drag}
width={width}
height={height}
opacity={opacity}
onClick={onClick}
>
...
</StyleComponent.InputLatexContent>
</>
);
-
item : drop 컴포넌트에서 전달 받을 정보를 입력한다.
- type: drop 컴포넌트와 같은 타입을 작성한 drag 컴포넌트에서만 반응한다.
- monitor: 내부 상태 저장소, 드래그의 진행 상태를 저장하고 있다.
- collect: 상태를 DOM 노드에 할당 할 수 있다. ex) isDragging (드래그 중)
-
useDrop
: 드래그 컴포넌트를 내려 놓는 컴포넌트에서 사용한다.
const [{ canDrop, isOver }, drop] = useDrop({
accept: 'box',
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
drop(item: { name: string; type: string; latex: string, isPossible: boolean }, monitor) {
if(item.isPossible) {
const clientOffset = monitor.getClientOffset();
handleClientOffset(clientOffset.x, clientOffset.y, item.latex);
}
else {
dispatch(changeAlertMode(1));
}
},
});
const isActive = canDrop && isOver;
return (
<>
...
<MathQuill
isBackgroundDropdownShow={backgroundDropdown}
isActive={isActive}
canDrop={canDrop}
latex={latex}
dragndrop={drop}
paintDropdown={paintDropdown}
/>
...
);
- drop(item, monitor): 드래그 대상이 drop 컴포넌트에 떨어졌을 때, 호출 된다.
- monitor.getClientOffset(): 드래그 대상의 y, x 좌표를 알 수 있다.