개발/자바스크립트

[리액트]react-beautiful-dnd

대왕판다 2022. 2. 14. 15:49

"아름답고 쉬운" React list drag and Drop

-

 

react-beautiful-dnd

Beautiful and accessible drag and drop for lists with React. Latest version: 13.1.0, last published: 10 months ago. Start using react-beautiful-dnd in your project by running `npm i react-beautiful-dnd`. There are 1175 other projects in the npm registry us

www.npmjs.com

 

손쉽게 드래그앤드롭 기능 / 애니메이션을 간단하게 사용 가능

 

 

위 그림처럼 DragDropContext -> Droppable -> Draggable로 감싸준다.

onDragEnd는 드래그가 끝났을때 실행될 함수를 넣어준다.

<DragDropContext onDragEnd={onDragEnd}>
    <Droppable droppableId="one">
      {(provided) => (
        <ul ref={provided.innerRef} {...provided.droppableProps}>
          <Draggable draggableId="first" index={0}>
          </Draggable>
        </ul>
      )}
    </Droppable>
</DragDropContext>

 

Draggable은 children으로 함수를 요구

  <Draggable draggableId="first" index={0}>
	{() => <li>One</li>}
  </Draggable>
  <Draggable draggableId="second" index={1}>
	{() => <li>Two</li>}
  </Draggable>

provided, snapshot처럼 주어지는 인자들을 위해 함수 형태로 요구한다. 

 

provided의 type definition을 보면

export interface DraggableProvided {
    // will be removed after move to react 16
    innerRef: (element?: HTMLElement | null) => any;
    draggableProps: DraggableProvidedDraggableProps;
    dragHandleProps?: DraggableProvidedDragHandleProps | undefined;
}

이런식으로 interface가 선언되어있다.

 

**

Draggable component에서 key는 draggableId와 동일해야한다.

요때 타겟이 되는 array 속 element가 string이 key가 될 수도 있다.

React에서 key는 보통 number였기때문에 헷갈릴수 있는 부분..!

https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/draggable.md

 

 

-

  const onDragEnd = ({ draggableId, destination, source }: DropResult) => {
    if (!destination) return;
    setToDos((oldToDos) => {
      const toDosCopy = [...oldToDos];
      toDosCopy.splice(source.index, 1);
      toDosCopy.splice(destination?.index, 0, draggableId);
      return toDosCopy;
    });

이런식으로 onDragEnd 함수까지 구현해 순서를 바꿔보니 부드럽게 잘 작동하지만,

순서가 바뀌지 않는 요소까지도 re-render되고있다.

요소가 단순히 문자만 render한다면 큰 문제가 없을수도 있지만,

api를 요청하거나 복잡한 게산을 해야 할 경우에는 문제가 발생할것

 

react memo를 활용해 prop이 바뀌지 않는다면 컴포넌트를 render하지 않게 하면 해결 할 수 있다.

export default React.memo(DraggableCard);

 

=>index가 바뀌는 요소들만 render된다!