설치
npm install react-dnd react-dnd-html5-backend
시작하기
프로바이더 정의
src / components / DndProviderLayer.tsx
"use client"; // 클라이언트 컴포넌트로 설정
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
export default function DndProviderLayer({ children }: { children: React.ReactNode }) {
const options = {
enableMouseEvents: true, // 마우스 이벤트 활성화
enableTouchEvents: true, // 터치 이벤트 활성화
enableKeyboardEvents: true, // 키보드 이벤트 활성화 (접근성)
ignoreContextMenu: true, // 우클릭 메뉴 무시
delayTouchStart: 0 // 터치 시작 지연시간 (밀리초)
}
return <DndProvider backend={HTML5Backend} options={options}>{children}</DndProvider>;
}
프로바이더 렌더링
src / app / layout.tsx
import DndProviderLayer from "@/lib/DndProviderLayer";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ko">
<body>
<DndProviderLayer>{children}</DndProviderLayer>
</body>
</html>
);
}
드래그 컴포넌트
import { useDrag } from 'react-dnd'
interface DragItemProps {
id: string
name: string
}
export const DragItem = ({ id, name }: DragItemProps) => {
// useDrag 훅을 사용하여 드래그 기능 설정
const [{ isDragging }, drag] = useDrag(() => ({
// 해당 드래그 아이템의 타입을 지정 (드롭 영역에서 이 타입을 받을 수 있는지 확인)
type: 'ITEM',
// 드래그할 때 전달할 데이터
item: { id, name },
// 드래그 상태 수집기 (collector)
// monitor를 통해 현재 드래그 상태를 실시간으로 파악
collect: (monitor) => ({
isDragging: monitor.isDragging() // 현재 드래그 중인지 여부
})
}))
return (
// drag ref를 DOM 요소에 연결하여 드래그 가능하게 만듦
<div
ref={drag as React.LegacyRef<HTMLDivElement>}
style={{ opacity: isDragging ? 0.5 : 1 }} // 드래그 중일 때 시각적 피드백
>
{name}
</div>
)
}
드롭 컴포넌트
import { useDrop } from 'react-dnd'
interface DropZoneProps {
onDrop: (item: any) => void
}
export const DropZone = ({ onDrop }: DropZoneProps) => {
// useDrop 훅을 사용하여 드롭 영역 설정
const [{ isOver }, drop] = useDrop(() => ({
// 이 영역이 받아들일 수 있는 드래그 아이템의 타입
accept: 'ITEM',
// 아이템이 드롭되었을 때 실행될 콜백
drop: (item) => onDrop(item),
// 드롭 상태 수집기 (collector)
// monitor를 통해 현재 드롭 영역의 상태를 실시간으로 파악
collect: (monitor) => ({
isOver: monitor.isOver() // 드래그 아이템이 드롭 영역 위에 있는지 여부
})
}))
return (
// drop ref를 DOM 요소에 연결하여 드롭 가능한 영역으로 만듦
<div
ref={drop as React.LegacyRef<HTMLDivElement>}
style={{
background: isOver ? '#e0e0e0' : 'white', // 드래그 아이템이 위에 있을 때 시각적 피드백
padding: '20px'
}}
>
드롭 영역
</div>
)
}
============================================================================================
개발자 모드에서 DND 영역 인식 오류가 발생하는 경우 해결방법
아래 라이브러리를 설치 후 프로바이더를 아래와 같이 수정합니다
이 방법의 단점은 드래그 시 기본 아이템 UI를 제공하지 않아 드래그 중 보여지는 UI가 없습니다.
이에 드래그 중 UI를 별도로 정의해야합니다.
테스트 때문에 개발자모드를 사용하는 거라면 콘솔로그 대신 alert로 찍어보십셔
설치
npm i react-dnd-touch-backend
수정
src / components / DndProviderLayer.tsx
"use client"; // 클라이언트 컴포넌트로 설정
import { DndProvider } from "react-dnd";
import { TouchBackend } from "react-dnd-touch-backend";
export default function DndProviderLayer({ children }: { children: React.ReactNode }) {
return (
<DndProvider backend={TouchBackend} options={{ enableMouseEvents: true }}>
{children}
</DndProvider>
);
}
'라이브러리' 카테고리의 다른 글
[html2canvas] html2canvas로 UI를 이미지로 다운로드 하기 (0) | 2025.08.04 |
---|---|
[ts-particle] 버블 애니메이션 컴포넌트 예시 코드(버블 프리셋 적용) (0) | 2025.04.27 |
[motion] 뷰포트 감지 훅(useInView) 사용 방법 (0) | 2025.04.27 |
dayjs 사용방법 | 시간을 년월일로 변경하는 방법 (1) | 2025.04.10 |
[Firebase] FCM을 활용한 웹 푸쉬 알림 구현방법 A to Z (1) | 2025.04.01 |