React 드래그 앤 드롭 구현

juno·2022년 9월 22일
2


핵심키워드

DragEvents

우선 4가지 이벤트의 차이를 알아야 합니다.

  • onDragStart: 드래그이벤트가 시작하는 박스의 인덱스를 useRef로 가지고 있는다.

  • onDragEnter: 마우스가 눌린 상태일때 이벤트가 일어나는 박스의 인덱스를 useRef로 가지고 있는다.(아래참고)

위 두개의 이벤트는 드래그되는 항목을 추적합니다.

  • onDragOver : 이 이벤트가 켜져있으면 불안해 집니다.
    이벤트를 억제합니다.

    다시 박스가 돌아가는거 보이시나요? 이런 애니메이션을 억제 시킵니다.

  • onDragEnd : 드래그를 놓을때 참조한 인덱스 값들을 사용하여 배열을 섞습니다.

코드

import React, { useRef, useState } from 'react';

export default function MoveBox() {
  const dragItem = useRef();
  const dragOverItem = useRef();
  const [list, setList] = useState([
    'Item 1',
    'Item 2',
    'Item 3',
    'Item 4',
    'Item 5',
    'Item 6',
  ]);

  const dragStart = idx => {
    dragItem.current = idx;
  };

  const dragEnter = idx => {
    dragOverItem.current = idx;
  };

  const drop = () => {
    const copyListItems = [...list];
    const dragItemConotent = copyListItems[dragItem.current];
    copyListItems.splice(dragItem.current, 1);
    copyListItems.splice(dragOverItem.current, 0, dragItemConotent);
    dragItem.current = null;
    dragOverItem.current = null;
    setList(copyListItems);
    console.log('드랍');
  };
  return (
    <>
      {list &&
        list.map((item, index) => (
          <div
            style={{
              backgroundColor: 'lightblue',
              margin: '20px 25%',
              textAlign: 'center',
              fontSize: '40px',
            }}
            onDragStart={() => dragStart(index)}
            onDragEnter={() => dragEnter(index)}
            onDragOver={e => e.preventDefault()}
            onDragEnd={drop}
            key={index}
            draggable>
            {item}
          </div>
        ))}
    </>
  );
}

Drop 코드 key point

  const drop = () => {
    // 재구성할 배열 생성
    const copyListItems = [...list];
    // 선택했던 div박스 따로 저장
    const dragItemConotent = copyListItems[dragItem.current];
    // 선택했던 div박스 배열에서 삭제
    copyListItems.splice(dragItem.current, 1);
    // 따로 저장한 div박스 dragEnter 참조했던 위치에 껴놓기  
    copyListItems.splice(dragOverItem.current, 0, dragItemConotent);
    // 참조했던 값 초기화
    dragItem.current = null;
    dragOverItem.current = null;
    // 재구성한 배열 넣기
    setList(copyListItems);
  };

깃헙 소스 코드

profile
안녕하세요 인터랙션한 웹 개발을 지향하는 프론트엔드 개발자 입니다. https://kimjunho97.tistory.com => 블로그 이전 중

4개의 댓글

comment-user-thumbnail
2022년 9월 24일

준호님!! 대박 감사합니다

1개의 답글
comment-user-thumbnail
2022년 9월 24일

1개의 답글