I T H

[React_Basic 4] TODO 리스트 만들기3 - Drag and Drop 본문

React Basic

[React_Basic 4] TODO 리스트 만들기3 - Drag and Drop

thdev 2024. 1. 25. 10:28

- Drag and Drop 기능을 사용하기 위해 설치 해준다.

npm install react-beautiful-dnd --save

 

-  Drag and Drop기능을 Lists.js에 넣어준다.

[Lists.js]

import React from "react";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";

export default function Lists({ todoData, setTodoData }) {
  const handleCompleteChange = (id) => {
    let newTodoData = todoData.map((data) => {
      if (data.id === id) {
        data.completed = !data.completed;
      }
      return data;
    });
    setTodoData(newTodoData);
  };

  const handleClick = (id) => {
    let newTodoData = todoData.filter((data) => data.id !== id); //클릭하지 않은 key값 데이터만 뜨게 됨.
    console.log("newTodoData", newTodoData);
    setTodoData(newTodoData);
  };

  const handleEnd = (result) => {
    console.log("result", result);

    if (!result.destination) return;
    const newTodoData = todoData;

    //1. 변경시키는 아이템을 배열에서 지워줌.
    //2. return 값으로 지워진 아이템을 잡아줌.
    const [reorderedItem] = newTodoData.splice(result.source.index, 1);

    //원하는 자리에 reorderedItem을 insert 해줍니다.
    newTodoData.splice(result.destination.index, 0, reorderedItem);
    setTodoData(newTodoData);
  };

  return (
    <div>
      <DragDropContext onDragEnd={handleEnd}>
        <Droppable droppableId="todo">
          {(provided) => (
            <div {...provided.droppableProps} ref={provided.innerRef}>
              {todoData.map((data, index) => (
                <Draggable
                  key={data.id}
                  draggableId={data.id.toString()}
                  index={index}
                >
                  {(provided, snapshot) => (
                    <div
                      key={data.id}
                      {...provided.draggableProps}
                      ref={provided.innerRef}
                      {...provided.dragHandleProps}
                      className={`${
                        snapshot.isDragging ? "bg-gray-400" : "bg-gray-100"
                      } flex items-center justify-between w-full px-4 py-1 my-2 text-gray-600 bg-gray-100 border rounded`}
                    >
                      <div className="items-center">
                        <input
                          type="checkbox"
                          defaultChecked={false}
                          onChange={() => handleCompleteChange(data.id)}
                        />
                        <span
                          className={
                            data.completed ? "line-through" : undefined
                          }
                        >
                          {data.title}
                        </span>
                      </div>
                      <div className="items-center">
                        <button
                          className="px-4 py-2 float-right"
                          onClick={() => handleClick(data.id)}
                        >
                          X
                        </button>
                      </div>
                    </div>
                  )}
                </Draggable>
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </div>
  );
}

[console.log화면]

- source의 index : 배열에서 제거할 인덱스

   const [reorderedItem] = newTodoData.splice(result.source.index, 1);

- destination의 index :  원하는 자리에 넣을 위치의 인덱스

    newTodoData.splice(result.destination.index, 0, reorderedItem);

 

[결과화면]