"아름답고 쉬운" React list drag and Drop
-
위 그림처럼 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였기때문에 헷갈릴수 있는 부분..!
-
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된다!
'개발 > 자바스크립트' 카테고리의 다른 글
[NextJS] 넥스트JS 개념 (0) | 2022.03.21 |
---|---|
[네스트js] 컨트롤러, 프로바이더, 모듈 + validation (0) | 2022.03.17 |
[리액트] React-hook-form (0) | 2022.01.30 |
[리액트] Recoil - state management (0) | 2022.01.19 |
[타입스크립트] 타입스크립트 기본개념 + 병합연산자 (0) | 2022.01.11 |