[javascript] Beautiful Dnd의 카스텀 드롭 대상 제어하기

Beautiful Dnd는 React 앱에서 드래그 앤 드롭 기능을 간편하게 구현할 수 있게 도와주는 라이브러리입니다. 이 라이브러리를 사용하면 사용자 인터페이스 요소를 드래그하여 다른 위치로 이동시킬 수 있습니다.

그러나 Beautiful Dnd는 드랍 대상 (drop target)을 관리하는 데 있어서 몇 가지 제한 사항이 있습니다. 기본적으로 Beautiful Dnd는 드래그 가능한 요소를 지정한 드롭 대상 컨테이너에만 드롭할 수 있도록 설정됩니다. 이러한 제한을 우회하여 더 많은 컨트롤을 제공하려면 몇 가지 추가 작업이 필요합니다.

아래에 예제 코드를 작성해보겠습니다.

import React from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

const data = [
  { id: '1', content: 'Item 1' },
  { id: '2', content: 'Item 2' },
  { id: '3', content: 'Item 3' }
];

const Container = () => {
  const handleDragEnd = (result) => {
    // 드래그가 끝났을 때 실행되는 함수
    const { destination, source, draggableId } = result;
    
    if (!destination) {
      // 드랍 대상이 없는 경우
      return;
    }

    if (destination.index === source.index) {
      // 드래그된 위치가 변하지 않은 경우
      return;
    }

    // 새로운 배열을 생성하여 순서를 변경
    const newData = Array.from(data);
    const [removed] = newData.splice(source.index, 1);
    newData.splice(destination.index, 0, removed);

    // 변경된 데이터를 업데이트
    setData(newData);
  };

  const setData = (newData) => {
    // 데이터 업데이트 함수
    // 실제 앱에서는 이 함수를 더 적절한 방법으로 구현해야 합니다
    console.log(newData);
  };

  return (
    <DragDropContext onDragEnd={handleDragEnd}>
      <Droppable droppableId="container">
        {(provided, snapshot) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            {data.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided, snapshot) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item.content}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};

export default Container;

위의 예제 코드는 Beautiful Dnd를 사용하여 드래그 앤 드롭 기능을 구현하는 간단한 컨테이너 컴포넌트입니다. data 배열은 드래그 가능한 요소를 나타내며, 이를 순서대로 화면에 렌더링합니다.

handleDragEnd 함수는 드래그가 끝났을 때 실행되는 함수로, 새로운 배열을 생성하여 순서를 변경하고 변경된 데이터를 업데이트합니다.

setData 함수는 데이터를 업데이트하는 함수로, 실제 앱에서는 이 함수를 더 적절한 방법으로 구현해야 합니다.

드롭 대상 컨테이너를 정의하고, Droppable 컴포넌트로 감싸 드래그 가능한 요소를 렌더링합니다. Draggable 컴포넌트는 각각의 드래그 가능한 요소를 나타내며, provided.draggablePropsprovided.dragHandleProps를 요소에 적용하여 드래그 액션을 활성화합니다.

이 예제 코드를 사용하면 Beautiful Dnd의 드롭 대상을 더욱 세밀하게 제어할 수 있습니다.