swimminginthecode DIVE!

FRONT/React JS Master

react-beautiful-dnd

dazz6 2025. 4. 15. 18:00

리액트에서 드래그 앤 드롭을 쉽게 구현할 수 있는 라이브러리가 있다.

react-beautiful-dnd 로, 드래그 앤 드롭 기능뿐만아니라 반응형 UI 및 애니메이션도 기본적으로 제공한다.

npm install react-beautiful-dnd
npm install --save-dev @types/react-beautiful-dnd

 

 return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="droppable">
        {(provided) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            {items.map((item, index) => (
              <Draggable key={item} draggableId={item} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );

 

위와 같이 jsx를 작성해 준다. 

이렇게 보면 아주 복잡해 보이지만... 실제로도 복잡하다. 그렇지만 라이브러리 없이 구현하는 건 훨씬 * 100 복잡하니까 이겨냈다.

종류 설명 필요 props
DragDropContext 드래그 앤 드롭을 관리하는 최상위 컨텍스트 onDragEnd : 드래그 종료시 호출되는 함수
Droppable 드래그한 항목을 놓을 수 있는 영역
드래그 가능한 항목들이 놓일 공간
droppableId : Droppable의 고유 식별자
provided : 드래그 가능 영역의 동작 관리
    .innerRef : Droppable의 DOM 요소 React에 연결
    .droppableProps : 영역에 필요한 속성 전달
    .placeholder : 위치 변화로 인한 레이아웃 문제 해결
Draggable 드래그할 수 있는 항목 정의
사용자가 드래그할 수 있는 요소
draggable Id : Draggable 의 고유 식별자
index : 항목 순서 정의
provided : 드래그 가능한 항목의 동작 관리
    .innerRef : Draggable 의 DOM 요소 React에 연결
    .draggableProps : 항목에 필요한 프로퍼티 전달
    .dragHandleProps : 클릭하여 드래그하도록 함

 

 

DragDropContext의 onDragEnd 는 드래그가 끝났을 때 실행된다.

onDragEnd 함수에는 순서를 재정렬하는 코드를 작성해 주었다.

const onDragEnd = (info: DropResult) => {
    console.log(info);
    const { destination, draggableId, source } = info;
    // destination (droppableId 보드 아이디, index 위치) : 목적지
    // draggableId : 드래그 중인 요소의 아이디
    // source (droppableId 보드 아이디, index 위치 : 출발지
    if (!destination) {
      return;
    }
    if (destination?.droppableId === source.droppableId) {
      // 같은 보드 내 이동
      setToDos((allBoards) => {
        const boardCopy = [...allBoards[source.droppableId]];
        const taskObj = boardCopy[source.index];
        boardCopy.splice(source.index, 1);
        boardCopy.splice(destination?.index, 0, taskObj);
        return {
          ...allBoards,
          [source.droppableId]: boardCopy,
        };
      });
    }
    if (destination?.droppableId !== source.droppableId) {
      // 다른 보드 이동
      setToDos((allBoards) => {
        const sourceBoard = [...allBoards[source.droppableId]];
        const taskObj = sourceBoard[source.index];
        const destinatinoBoard = [...allBoards[destination.droppableId]];
        sourceBoard.splice(source.index, 1);
        destinatinoBoard.splice(destination?.index, 0, taskObj);
        return {
          ...allBoards,
          [source.droppableId]: sourceBoard,
          [destination.droppableId]: destinatinoBoard,
        };
      });
    }
  };

 

.splice를 이용해서 삭제하고 삽입하는 방식을 사용했다.

 

강의를 들으면서 진도가 너무 빠르다고 처음 느꼈다... ㅠㅠ

반복해서 수강 + 코드 줄 단위로 이해 < 하면서 어느 정도 이해했다고 느껴도 응용이 어려웠는데,

7강 마지막에 코드 챌린지의 과제를 구현하면서 나름 활용할 수 있게 된 것 같다.

 

기획 중인 프로젝트에 드래그 앤 드롭을 적용할 수 있는 기능이 있어서, 적극적으로 써 보려고 한다!

 

확실하게 일반 JavaScript 문법에 대해서 부족하다고 느꼈다. splice 는 자주 쓰는 함수인데도 헷갈려서...

코테를 Js 로도 풀어 봐야 할 것 같다... 정말 공부는 끝이 없구ㄴㅏ...

 

 

'FRONT > React JS Master' 카테고리의 다른 글

useRef  (0) 2025.04.14
React.memo  (0) 2025.01.27
React-hook-form  (0) 2024.12.03
Recoil  (0) 2024.12.02
ReactQuery (useQuery)  (0) 2024.11.28