React Dnd-Kit 시작하기

이 기사에서는 반응을 위해 드래그 앤 드롭 라이브러리 중 하나를 사용할 것입니다. react-dnd , dnd-kit & react-beautiful-dnd 과 같은 반응에 좋은 드래그 앤 드롭 라이브러리가 거의 없습니다.

우리는 오늘 dnd-kit을 살펴볼 것입니다. 이 라이브러리를 사용하는 이유는 많은 사용 사례, 후크 가용성, 경량성 등을 지원하기 때문입니다.

시작하려면 create-react-app으로 반응 앱을 만들고 필요한 라이브러리를 설치하십시오.
npx create-react-app react-dndkit-egnpm install --save @dnd-kit/core @dnd-kit/sortable
@dntkit/core & @dndkit/sortable 이들은 기본 dragndrop 기능을 지원하는 데 필요한 두 개의 라이브러리입니다. 라이브러리는 또한 @dnd-kit/utilities , @dnd-kit/modifiers , @dnd-kit/accessibility 와 같은 다른 라이브러리와 함께 다양한 기타 기능을 지원합니다. 이들 각각은 웹 사이트에서 읽을 수 있습니다.

우선 드래그 가능/정렬 가능한 구성 요소를 래핑할 구성 요소를 만들 것입니다. 간단한 용어로 dnd의 전체 아이디어는 항목을 드래그하거나 이동할 수 있는 컨테이너를 포함하여 구성 요소에 관한 코드가 다소 보일 것입니다. 이렇게 sortable-component-complete-code

...
# e.g code snippet
export function SortableItem(props) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
  } = useSortable({id: props.id}); 

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  if(props.handle) {
    return (<div ref={setNodeRef} style={style} {...attributes} className={'pos-relative'}>
      {
        props.handle ? 
        <span className='dragHandleClass' {...listeners}>
          # some svg/img/htmlelement
        </span>
        : null
      }
      {props.children}
    </div>)
  }

  return (
    <div ref={setNodeRef} style={style} {...attributes}   {...listeners} className={'pos-relative'}>
      {props.children}
    </div>
  );
}
...


위의 코드는 드래그/정렬해야 하는 구성 요소에 대한 래퍼 역할을 합니다. 이 기사의 뒷부분에서 핸들 속성에 대해 설명하고 모든 항목을 고유하게 식별할 수 있도록 id 속성이 useSortable 후크로 전달됩니다.

이제 그리드 및 행 요소를 이동/정렬할 수 있도록 DndContext 및 SortableContext가 필요한 컨테이너를 생성하기 위해 정렬하거나 드래그할 수 있는 여러 항목을 포함하는 구성 요소를 생성해 보겠습니다.

DndContext는 센서, 충돌 감지 등 몇 가지 소품을 사용합니다. 이러한 기능에는 전체 dragndrop 상호 작용 전후에 사용할 수 있는 기능인 handleDragStart 및 handleDragEnd와 같은 기능도 포함됩니다.
Similarly SortableContext takes few props , here we will have to pass items which should be an array on uniqueIds & this should be same as that we have passed to sortableItem above.
컨텍스트의 코드는 다음과 유사해야 합니다sortable-context-complete-code.

...
# e.g sortable context/container

<DndContext 
          id={'grid-dnd-basic'}
          onDragEnd={handleDragEnd}
          sensors={sensors}
          collisionDetection={closestCenter}
        >
            <SortableContext 
              id={'grid-sort-contextbasic'}
              items={items.map((i) => i?.id)}
            >
              {items.map(value => {

                return (
                  <SortableItem handle={true} key={value?.id} id={value?.id} >
# sortableItem Content
                  </SortableItem>
                )
              })}
            </SortableContext>
          </DndContext>
...



이 시점에서 우리는 드래그 앤 드롭에 관한 구성 요소 설정을 마쳤습니다. 이제 handleDragStart/handleDragEnd와 같은 함수에 핸들러를 추가해야 합니다. 이들에 대한 코드는 dnd-kit 문서에서 제공하는 것과 거의 유사합니다. 유일한 변경 사항은 항목 속성입니다. 핸들러 함수에 전달되는


  function handleDragEnd(event) {
    const {active, over} = event;

    if (active.id !== over.id) {
      setItems((items) => {
        const oldIndex = (items.map(i => i.id)).indexOf(active.id);
        const newIndex = (items.map(i => i.id)).indexOf(over.id);

        return arrayMove(items, oldIndex, newIndex);
      });
    }
  }


위의 코드에서 모든 것이 sortableItem 및 sortableContext에 전달되는 uniqueId에 매핑되므로 map 함수를 사용하여 indexOf 함수에 대한 ID만 전달하는 것을 볼 수 있습니다.
따라서 dndContext 및 sortableContext를 사용하여 정렬하기 위한 dnd-kit 구현이 거의 준비되었습니다.
Now lets visit the handle prop that we have used earlier in our sortableItem, so we can see useSortable provides a listeners now if we want to drag the item using some handler and not the actual item then we can use handle prop to apply listener to the drag-handler directly, in this way we will be able to drag via some handler and not he actual item
# e.g handle implementation
...
  if(props.handle) {
    return (<div ref={setNodeRef} style={style} {...attributes} className={'pos-relative'}>
      {
        props.handle ? 
        <span className='dragHandleClass' {...listeners}>
          # svg/image/html-element
        </span>
        : null
      }
      {props.children}
    </div>)
  }
  ...


이제 전체적으로 sensors에 대해 이야기해 보겠습니다. 예를 들어 문서에서 이와 유사하게 보이는 기본 센서 구현을 사용할 것입니다.

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );


이제 이러한 사용 센서는 속성activationConstraint이 있는 객체로 두 번째 매개변수를 취합니다. 이제 일부 픽셀 이동 후에만 센서를 활성화하는 데 사용할 수 있습니다code.

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

The scenarios where this can be used is when you have an click listener to you sortableItem & you don't use drag-handle, so that we can uniquely identify click & drag events, without this constraint event click will be treated as drag events & our drag-handler functions like onDragEnd & onDragStart will be triggered.
이 문서는 주로 dndContextsortable 사전 설정과 관련된 주제를 다룹니다. 자세한 내용은 dnd-kit 웹 사이트에서 읽을 수 있습니다.

기사와 관련된 코드는 GithubLinkgh-pages에 있습니다.

좋은 웹페이지 즐겨찾기