티스토리 뷰
JSON을 사용한 이유
외부 컴포넌트에 있는 데이터를 드래그로 데이터를 전달하기 위해 dataTransfer.setData를 사용함
dataTransfer API객체를 사용하려면 문자열로 변환해야 하기 때문
쥬스탄드 등으로 전역 상태를 만들어 관리하는 방법도 있으나 dataTransfer를 사용하는 게 훨씬 간결하기 때문(보일러플레이트)
dataTransfer란?
HTML5의 드래그 앤 드롭 API에 속하는 객체
드래그 앤 드롭 작업 동안 드래그된 데이터를 저장하고 전달하는 데 사용된다
dataTransfer 객체의 메서드와 속성
1. setData(format, data): 드래그된 데이터 설정
첫 번째 매개변수는 데이터 형식 지정, 두 번째 매개변수에는 설정할 데이터 전달
2. getData(format): 드롭 이벤트 핸들러에서 드래그된 데이터 추출
매개변수는 추출할 데이터의 형식 지정
3. clearData(format): 특정 형식의 드래그 데이터 삭제
4. setDragImage(image, xOffset, yOffset): 드래그 중에 사용할 커스텀 드래그 이미지 설정(css)
dataTransfer 외 다른 방법
Custom Events
드래그 이벤트를 통해 커스텀 이벤트 생성, 해당 이벤트에 데이터를 포함시켜 외부 컴포넌트에 전달할 수 있다.
이 방법은 데이터를 직접 넘기는 대신 이벤트를 통해 컴포넌트 간 통신을 가능하게 한다
Context API
React Context API로 드래그 이벤트 핸들러에서 상태를 업데이트하고, 해당 상태를 Context를 통해 하위 컴포넌트에 전달할 수 있다.
Redux 또는 다른 상태 관리 라이브러리
드래그 이벤트 핸들러에서 상태를 업데이트하고, 외부 컴포넌트에서 해당 상태를 구독하여 사용할 수 있다.
React Props
드래그 이벤트 핸들러에서 상위 컴포넌트로 데이터를 전달할 수 있다.
Drag and drop으로 현재 플리 추가하기
드래그할 요소에 draggable='true'를 설정해 줘야 드래그가능
onDragStart는 드래그 시작할 때 작동하는 함수(데이터 저장)
draggable='true'
onDragStart={(e) => {
dragHandler(e, item)
}}
예시코드
<li
draggable='true'
onDragStart={(e) => {
dragHandler(e, item)
}}
key={item.musicId}
className={`mr-6 w-[144px] list-none bg-[#ffffff19] ${itemShadow} overflow-hidden rounded-[2rem] border-4 border-[#00000070] p-2 text-center`}
>
<div>
<div className='group relative mb-2 h-[120px] w-[120px] overflow-hidden rounded-full border-2 border-[#ffffff19]'>
<figure className='h-[120px] w-[120px] [&_img]:h-auto [&_img]:w-full'>
<Image
className='group-hover:blur-sm'
src={item.thumbnail}
width={120}
height={120}
alt={`${item.musicTitle} 앨범 썸네일`}
/>
</li>
드래그 이벤트인 dragHandler는 모든 컴포넌트에서 쓸 거니까 Util에 빼놓음
export const dragHandler = (
e: React.DragEvent<HTMLLIElement>,
item: MusicInfoType,
) => {
e.dataTransfer.setData(
'musicInfo',
JSON.stringify({
musicSource: item.thumbnail,
musicId: item.musicId,
musicTitle: item.musicTitle,
musicArtist: item.artist,
musicLyrics: item.lyrics,
musicRunTime: item.runTime,
musicUrl: item.musicSource,
}),
)
}
Drop 영역
onDrop 드롭이벤트가 일어났을 때 실행되는 함수
onDragOver 드래그된 요소를 해당 영역 위로 드롭할 수 있도록 허용해 줌
onDrop={dropHandler}
onDragOver={dragOverHandler}
예시코드
<div
className='mt-[16px] flex max-h-[250px] min-h-[250px] flex-col overflow-y-auto overflow-x-hidden'
onDrop={dropHandler}
onDragOver={dragOverHandler}
>
{customPlayList.length === 0 && (
<div className='flex flex-col items-center text-[18px] opacity-50'>
음악을 추가해주세요
</div>
)}
드래그로 가져온 데이터를 드롭함수내부에서 제이슨파싱 해서 사용하면 됨
const musicInfo = JSON.parse(e.dataTransfer.getData('musicInfo'))
드래그오버이벤트 참고할 것
<div
onDragOver={(e) => {
e.preventDefault(); // 드래그된 요소를 이 영역 위로 드롭할 수 있도록 허용
// 추가적인 스타일링이나 표시를 설정할 수 있음
}}
>
드롭 영역
</div>
'TIL > 최종프로젝트' 카테고리의 다른 글
[최종프로젝트] 플레이 리스트 인덱스 변경 드래그앤 드롭 (세션 저장안됨) (0) | 2024.04.26 |
---|---|
[최종프로젝트] 드래그 앤 드롭 라이브러리 (0) | 2024.04.24 |
[최종프로젝트] 재생중인 노래 삭제 시 상태 반영 (0) | 2024.04.18 |
[최종프로젝트] 테일윈드 (tailwind CSS) (0) | 2024.04.16 |
[최종프로젝트] 현재 재생 상태 유지 (State) (0) | 2024.04.15 |