프로젝트/Task 어플리케이션
1120 드래그 앤 드롭 기능 만들기
thinktank911
2025. 11. 20. 18:06
드래그 앤 드롭 기능 만들기
DragDropContext
Droppable
Draggable 셋팅
// App.tsx
<DragDropContext onDragEnd={handleDragEnd}>
<LIstsContainer lists={lists} boardId={getActiveBoard.boardId} />
</DragDropContext>
// LIstsContainer -> List.tsx
<Droppable droppableId={list.listId}>
{provided => (
<div
className={listWrapper}
ref={provided.innerRef}
{...provided.droppableProps}
>
<div className={header}>
<div className={name}>{list.listName}</div>
<GrSubtract
className={deleteButton}
onClick={()=> handleListDelete(list.listId)}
/>
</div>
{list.tasks.map((task, index) => (
<div
onClick={() => handleTaskChange(boardId, list.listId, task)}
key={task.taskId}
>
<Task
index={index}
id={task.taskId}
boardId={boardId}
taskName={task.taskName}
taskDescription={task.taskDescription}
/>
</div>
))}
{provided.placeholder}
<ActionButton
boardId={boardId}
listId={list.listId}
/>
</div>
)}
</Droppable>
// Task.tsx
<Draggable draggableId={id} index={index}>
{(provided) => (
<div
className={container}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div className={title}>{taskName}</div>
<div className={description}>{taskDescription}</div>
</div>
)}
</Draggable>
onDragEnd 함수 생성
const handleDragEnd = (result: any) => {
console.log(result);
const { destination, source, draggableId } = result;
console.log('lists', lists);
const sourceList = lists.filter(list => list.listId === source.droppableId)[0];
console.log('sourceList', sourceList);
// const destinationList = lists.filter(list => list.listId === destination.droppableId)[0];
// if (!result.destination) return;
dispatch(
sort({
boardIndex: boards.findIndex(board => board.boardId === activeBoardId),
droppableIdStart: source.droppableId,
droppableIdEnd: destination.droppableId,
droppableIndexStart: source.index,
droppableIndexEnd: destination.index,
draggableId
})
)
sort 로직 생성하기
boardsSlice.ts
sort: (state, {payload} : PayloadAction<TSortAction>) => {
// same list
if (payload.droppableIdStart === payload.droppableIdEnd) {
const list = state.boardArray[payload.boardIndex]
.lists.find(
list => list.listId === payload.droppableIdStart
);
// 변경시키는 아이템 배열에서 지워준다.
// return 값으로 지워진 아이템 잡아준다.
const card = list?.tasks.splice(payload.droppableIndexStart, 1);
// card! : undefined는 없다.
list?.tasks.splice(payload.droppableIndexEnd, 0, ...card!);
}
// other list
if (payload.droppableIdStart !== payload.droppableIdEnd) {
const listStart = state.boardArray[payload.boardIndex].lists.find(
list => list.listId === payload.droppableIdStart
);
const card = listStart?.tasks.splice(payload.droppableIndexStart, 1);
const listEnd = state.boardArray[payload.boardIndex].lists.find(
list => list.listId === payload.droppableIdEnd
);
listEnd?.tasks.splice(payload.droppableIndexEnd, 0, ...card!);
}
}