DragAndDrop(DnD)구현 (1)

띵킹하는 개발자·2023년 4월 19일
1

목록 보기
1/7
post-thumbnail

나는 팀 프로젝트를 하던 중 DragAndDrop이라는 기능을 구현하라고 하여 구글링을 통하여 DnD의 구현을 도와주는 라이브러리를 찾던 중
react-beautiful-dnd라는 라이브러리를 찾게되었다.
react에서 설치는 npm i react-beautiful-dnd이고,
typescript를 사용할 경우 npm install --save @types/react-beautiful-dnd로 install을 받으면 된다.

react-beautiful-dnd에서 지원하는 것들

  • DragDropContext
    : DragDropContext는 DnD가 일어나는 전체영역을 말한다.
    여기서 드래그 앤 드랍기능을 구현을 하게된다 (onDragEnd={...})

  • Draggable
    : Draggable은 쉽게 말해서 drag당하는 객체를 묶어주는 태그이다.


  • Droppable
    : Droppable은 drop을 할 수 있게 해주는 kanban보드 영역이다

    이렇게 보면 더 쉽게 이해할 수 있을것이다.

    코드를 짜면서 더 자세히 알아보자.
    (먼저 이 코드는 내가 실제로 팀프로젝트를 하면서 짠 dnd코드임을
    밝힙니다, 진짜 이거 에러때문에 근 2주를..)

    지금 보이는 사진은 현재 웹사이트를 켜놓고 기록보기 페이지로 들어간 화면이다


    현재 웹사이트 kanban board는 이런식으로 생겼다 이제 kanban board안에 있는 Card들을 자신의 컬럼 및 다른 컬럼들로 움직일 수 있게 만드는 코드를 짜야한다.

DragDropContext

DragDropContext를 전체 컬럼을 감싸야한다. 그래야 저 안에 있는 컬러미낄 dnd가 가능하기에...

<DragDropContext>
           <div className="record-body">
             <RecordKanban
               emoji="📌"
               title="상시"
               data={state?.applicationMap?.ALWAYS}
             />
             <RecordKanban
               emoji="🌙"
               title="시작 전"
               data={state?.applicationMap?.NOT_STARTED}
             />
             <RecordKanban
               emoji="🌞"
               title="진행 중"
               data={state?.applicationMap?.IN_PROGRESS}
             />
             <RecordKanban
               emoji="🌚"
               title="완료됨"
               data={state?.applicationMap?.DONE}
             />
           </div>
         </DragDropContext>

이렇게 kaban-board body를 감싸게 되면 이 안에서 DraggableDroppable을 사용할 수 있다.
참고로 Droppable을 사용할때는 고유의 키 값이 droppableId를 string형태로 주어야 한다(uuid로 줘도 상관x)

코드를 짜보면

Droppable

<DragDropContext onDragEnd={handleDragEnd}>
            <div className="record-body">
              <Droppable droppableId="ALWAYS">
                {provided => (
                  <div ref={provided.innerRef} {...provided.droppableProps}>
                    <RecordKanban
                      emoji="📌"
                      title="상시"
                      data={state?.applicationMap?.ALWAYS}
                    />
                  </div>
                )}
              </Droppable>
              <Droppable droppableId="NOT_STARTED">
                {provided => (
                  <div ref={provided.innerRef} {...provided.droppableProps}>
                    <RecordKanban
                      emoji="🌙"
                      title="시작 전"
                      data={state?.applicationMap?.NOT_STARTED}
                    />
                  </div>
                )}
              </Droppable>
              <Droppable droppableId="IN_PROGRESS">
                {provided => (
                  <div ref={provided.innerRef} {...provided.droppableProps}>
                    <RecordKanban
                      emoji="🌞"
                      title="진행 중"
                      data={state?.applicationMap?.IN_PROGRESS}
                    />
                  </div>
                )}
              </Droppable>
              <Droppable droppableId="DONE">
                {provided => (
                  <div ref={provided.innerRef} {...provided.droppableProps}>
                    <RecordKanban
                      emoji="🌚"
                      title="완료됨"
                      data={state?.applicationMap?.DONE}
                    />
                  </div>
                )}
              </Droppable>
            </div>
          </DragDropContext>

이렇게 짤 수 있는데 이떄 provided는 dnd 인터랙션에서 지원하는 객체인데 여기서 지원하는 프로퍼티 중 innerRef가 있다.
innerRef는 ref 객체에 연결해야 하는 프로퍼티를 포함한다.
그래서 무조건 넣어줘야하는 코드이다.

Draggable

아까 말했듯이 Draggable은 drag 당하는 객체를 태그로 묶어주면 된다.

 <Draggable key={k.title} draggableId={k.title} index={index}>
              {(provided, snapshot) => (
                <div
                  ref={provided.innerRef}
                  {...provided.draggableProps}
                  {...provided.dragHandleProps}
                  style={{
                    ...provided.draggableProps.style,
                    opacity: snapshot.isDragging ? "0.5" : "1",
                  }}
                >
                  <Card
                    applicationId={k.applicationId}
                    emoji={k.emoji}
                    title={k.title}
                    endDate={k.endDate}
                    starteDate={k.startDate}
                    status={k.status}
                    numberOfReplies={k.numberOfReplies}
                    key={index}
                  />
                </div>
              )}
            </Draggable>

여기서 snapshot이라는 변수를 호출을 했는데 얘는 그냥 객체를 드래그 했을 때 그 해당 객체에게 주는 style을 줄 수 있다.
DraggableDroppable처럼 draggableId를 주어야한다 여기 있는 id도 string type이어야 한다.

이제 함수구현은 다음 블로그에서 구현하자!

profile
모든것은 띵킹으로 이루어지는 것

0개의 댓글