" 선배 드래그해주세요~ 드롭도 같이? "
자 오늘 필자는 저 카드를 드래그하여 빈곳에 드롭하여 적용시키는 일을 저지를거다
이곳에 많은 기능을 모아두었으니 참고하면 좋을 거 같다!
https://inpa.tistory.com/entry/드래그-앤-드롭-Drag-Drop-기능#
페이지 안에 먼저 다 구현하고 나중에 컴포넌트를 따로 만들 예정이다, 먼저 초기 구성된 사진을 보면
이렇게 <PlayerCard> 컴포넌트는 만들어진 상태이고 선수 정보 값을 map으로 가져오는 형태로
{startingMember.map((player, index) => (
<div
style={{
transform: "scale(1)",
}}
onClick={handlePlayerCardClick(player.pcode)}
key={index}
className={`absolute cursor-pointer ${getPositionStyle(
player.position_translated || player.position
)}`}
>
<PlayerCard
name={player.name}
imageUrl={player.imageUrl}
num={player.num}
position_translated={
player.position_translated || player.position
}
rating={player.rating}
pcode={player.pcode}
changeinn={player.changeinn}
/>
</div>
))}
갖춰놓은 형태도 마지막엔 여기서 몇가지 요소를 추가하니 잘 관찰하도록 하자!
먼저 와이어프레임에서 만든 빈칸 Image를 똭! 가져온다
<Image
onDrop={handleDrop}
onDragOver={handleDragEnter}
src="/images/drag.svg"
alt="빈 칸"
width={150}
height={190}
/>
그리고 드롭할 선수의 droppedPlayer 상태를 추가하여 드래그 앤 드롭된 PlayerCard 정보를 저장한다 (아직 문제 있음)
const [droppedPlayer, setDroppedPlayer] = useState(null);
handleDragStart 함수: 드래그가 시작될 때 player 정보를 데이터 전송 객체에 저장한다 (트러블 슈팅-> (player)이름을 못찾는다)
const handleDragStart = (event: React.DragEvent<HTMLImageElement>) => {
event.dataTransfer.setData("player", JSON.stringify(player));
};
handleDrop 함수: 드롭된 데이터를 droppedPlayer 상태로 설정하여 이미지를 대체한다
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const data = event.dataTransfer.getData("player");
if (data) {
setDroppedPlayer(JSON.parse(data));
}
};
조건부 렌더링: droppedPlayer 상태가 null일 경우 Image 컴포넌트를, 그렇지 않을 경우 PlayerCard 컴포넌트를 렌더링하게 조건을 만든다
<div
onDrop={handleDrop}
onDragOver={handleDragEnter}
style={{ width: 150, height: 190, border: "1px dashed gray" }}
>
{droppedPlayer ? (
<PlayerCard
name={droppedPlayer.name}
imageUrl={droppedPlayer.imageUrl}
num={droppedPlayer.num}
position_translated={droppedPlayer.position_translated || droppedPlayer.position}
rating={droppedPlayer.rating}
pcode={droppedPlayer.pcode}
changeinn={droppedPlayer.changeinn}
/>
) : (
<Image
src="/images/drag.svg"
alt="빈 칸"
width={150}
height={190}
/>
)}
</div>
요롷게 해주면 참 보기 싫은 빨간줄 파티가 이뤄진다 이유가 뭘까?
바로 나는 next.js와 typescript를 쓰기 때문이다 그래서 타입을 지정해줘야하는데 일단은 빨리 넘어가기 위해
any를 집어넣어주겠다.
그러면 아까 있던 " 드롭할 선수의 droppedPlayer 상태를 추가하여 드래그 앤 드롭된 PlayerCard 정보를 저장한다 (문제 해결)" 가 완료
const [droppedPlayer, setDroppedPlayer] = useState<any>(null);
그리고 이번에는 두번째 트러블
"handleDragStart 함수: 드래그가 시작될 때 player 정보를 데이터 전송 객체에 저장한다 (트러블 슈팅-> (player)이름을 못찾는다)"
먼저 이 함수를 쓰기위하여
를
PlayerCard 컴포넌트들을 드래그 가능하도록 draggable 속성을 추가하고 ,
handleDragStart 함수에 드래그 시작 시 (player) 데이터를 dataTransfer 객체에 저장합니다 json형식으로
그리고, 역시나 typescript 죠?
const handleDragStart =
(player: any) => (event: React.DragEvent<HTMLDivElement>) => {
event.dataTransfer.setData("player", JSON.stringify(player));
};
이런식으로 마무리해주면 된다!
이후 컴포넌트화하여 완료해주었다
하지만 저 영상과 같이 교체는 되지만, 다시 빈칸으로 삭제가 되지 않는 문제점이 있다
그래서 추가로 삭제하는 함수를 만들어주었다.
const handleRemovePlayer = (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();// 전파막기
setDroppedPlayer(null);
}; //삭제기능 함수
??
handleRemovePlayer 함수 내부에서 event.stopPropagation()을 사용하지 않으면,
삭제 버튼을 클릭했을 때 클릭 이벤트가 부모 요소로 전달될 수 있다.
이것은 의도하지 않은 부작용을 일으킬 수 있으며, 예를 들어 부모 요소가 클릭 이벤트를 처리하는 다른 핸들러를 가지고 있을 때 문제가 될 수 있다.
이후
return값에 추가하여 삭제까지 완료가 되었다 ~!
[유데미x스나이퍼팩토리] UI/UX 포트폴리오 과정 2기 - 사전직무교육 4일차 UX - 피그마 / UX 기획 (1) | 2024.11.21 |
---|---|
[유데미x스나이퍼팩토리] UI/UX 포트폴리오 과정 2기 - 사전직무교육 3일차 UX - 피그마 / UX 기획 (4) | 2024.11.20 |
[유데미x스나이퍼팩토리] UI/UX 포트폴리오 과정 2기 - 사전직무교육 2일차 UX - User eXperience / 피그마 (30) | 2024.11.19 |
[유데미x스나이퍼팩토리] UI/UX 포트폴리오 과정 2기 - 사전직무교육 1일차 UI / UX (4) | 2024.11.18 |
[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 1기 - 사전직무교육 1일차 후기 (0) | 2024.05.26 |