Atlassian에서 만든 React DND 라이브러리 react-beautiful-dnd를 사용해 안전하게 dnd를 구현해보자.
npm add react-beautiful-dnd
npm add -D @types/react-beautiful-dnd
타입스크립트를 사용한다면 위의 방식 두가지를 통해서 설치를 해준다.
따라서 index.js에서 strict모드를 지워주도록 하자!
삭제 전
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
삭제 후
ReactDOM.render(
<App />
document.getElementById('root')
);
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
const DndContainer = ({ item, setItem }: any) => {
return (
<DragDropContext>
<Droppable droppableId="lists">
{provided => (
<div className="lists" {...provided.droppableProps} ref={provided.innerRef}>
// 여기에 움직일 컴포넌트를 넣어준다.
</div>
)}
</Droppable>
</DragDropContext>
);
};
export default DndContainer;
DragDropContext를 통해서 ContextAPI의 Provider 처럼 DND의 상태를 제공해주는 역할을 한다고 보면 될 것같다. 이 안에서 onDragEnd 등 다양한 DND 이벤트를 등록해준다.
Drop할 수 있는 영역으로 명시한다.
Drag할 수 있는 영역으로 컴포넌트를 감싸준다.
droppableId
✔️ 드롭 가능한 영역을 구분할 id를 표시한다. ex) todo, doing, done
provided
<Droppable droppableId="droppable-1">
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
Good to go
{provided.placeholder}
</div>
)}
</Droppable>
✔️ provided.innerRef
라이브러리에서 컴포넌트 DOM을 조작하기 위해서 필수로 등록해 줘야한다.
✔️ provided.droppableProps
<div data-rbd-droppable-id="droppable" data-rbd-droppable-context-id="1">
✔️ provided.placeholder
snapshot
snapshot.isDraggingOver
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
style={{ background: snapshot.isDraggingOver ? 'pink' : 'gray' }}
>
{...}
{provided.placeholder}
</div>
)}
{items.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>
))}
- 각 컴포넌트에 유익한 id를 지정해줘야 한다.
- key와 droppableId, draggableId는 같아야한다!!
- Droppable의 provided와 Draggable의 provided는 다른 역할임을 유의해야한다.