인프런 커뮤니티 질문&답변

chori님의 프로필 이미지
chori

작성한 질문수

따라하며 배우는 리액트 A-Z[19버전 반영]

Drag and Drop 기능 추가하기

코드를 동일하게 한 것 같은데, 드래그 기능 작동이 안됩니다. 이유가 궁금합니다.

작성

·

3.4K

2

코드를 동일하게 한 것 같은데, 드래그 기능 작동이 안됩니다. 이유가 궁금합니다.

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

export default function List({ todoData, setTodoData }) {
  const handleClick = (id) => {
    let newTodoData = todoData.filter((data) => data.id !== id);
    console.log("newTodoData", newTodoData);
    //this.setState({ todoData: newTodoData });
    setTodoData(newTodoData);
  };

  const handleCompleteChange = (id) => {
    let newTodoData = todoData.map((data) => {
      if (data.id === id) {
        data.complited = !data.complited;
      }
      return data;
    });
    //this.setState({ todoData: newTodoData });
    setTodoData(newTodoData);
  };

  return (
    <div>
      <DragDropContext>
        <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 border rounded`}
                    >
                      <div className="items-center">
                        <input
                          type="checkbox"
                          defaultChecked={data.complited}
                          onChange={() => handleCompleteChange(data.id)}
                        />{" "}
                        <span
                          className={
                            data.complited ? "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>
  );
}

답변 7

7

저도 동일한 에러가 발생했는데, 검색해서 해결책 찾았습니다.
https://github.com/atlassian/react-beautiful-dnd/issues/2396

index.js 화일에서

<React.StrictMode></React.StrictMode>
제거하니까 바로 작동 되네요!!!

저도 지금 이거 작성하러 들어왔는데 이미 현답이 있었네요 ㅎㅎ

저는 이거 주석처리해도 안되는데..

A setup problem was encountered.> Invariant failed: Draggable[id: 1665382381504]: Unable to find drag handle

저도 이것때문에 계속 안되었는데 하드코딩에 계속 돌려봤는데 결국 여기서 답을 얻었네요!

 

1

처음부터 끝까지 드래그앤드롭을 못했네요; 빨리 답변좀 달아주세요!!!

혹시 해결하셨나요?? 저도 동일한 문제가 발생해서요ㅠㅠ

1

handleEnd 넣어도 계속 에러만 나는데 어떻게 해야하나요? 강의에 안나와요
<React.StrictMode></React.StrictMode> 이거 제거도 해봤는데 아무소용이 없네요?

무슨 좋은 해결책 없을까요? 못넘어가고 잇어요 ㅜ

1

John Ahn님의 프로필 이미지
John Ahn
지식공유자

안녕하세요 chori님! 
handleEnd 함수는 아래와 같이 설명을 봐주시면 됩니다 ! 

const handleEnd = (result) => {
// result 매개변수에는 source 항목 및 대상 위치와 같은 드래그 이벤트에 대한 정보가 포함됩니다.
console.log(result);
// 목적지가 없으면(이벤트 취소) 이 함수를 종료합니다.
if (!result.destination) return;

// 리액트 불변성을 지켜주기 위해 새로운 todoData 생성
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);
localStorage.setItem("todoData", JSON.stringify(newTodoData));
};

또한 onDragEnd는 이 라이브러리 설명서에 봐도 이걸 특정해서 설명해놓지는 않았습니다. 
https://github.com/atlassian/react-beautiful-dnd/blob/HEAD/docs/api/drag-drop-context.md

왜냐면 이름 자체가 onDragEnd 뭐하는 애인 지를 알려주는 애이기 때문입니다. 
Drag가 끝나는 이벤트가 발생했을 때 어떠한 함수를 호출시켜주는 애입니다. 
그 함수가 handleEnd입니다 
감사합니다^^.

chori님의 프로필 이미지
chori
질문자

안녕하세요, 답변 감사합니다.

해당 기능 중 드래그 기능 자체가 작동하지 않아, 확인해보니 개발자 도구에서 아래와 같은 에러가 발생하고 있었습니다.

Invariant failed: Cannot find droppable entry with id [todo]👷‍ This is a development only message. It will be removed in production builds.

번역하면 <Droppable droppableId="todo"> id가 todo인것을 찾지 못한다고 나오는것 같은데, 이 todo가 따로 명시 된 곳이 있을까요?

0

이강의 후 x 버튼과 edit 정렬이 이상해졌어요 ㅜ

0

strictmode 유지하고 싶으신 분들은 @hello-pangea/dnd 이거로 대체하시면 코드 동일하게 작동합니다.

0

이거 추가해보실래요??

  <DragDropContext onDragEnd={handleEnd}>
chori님의 프로필 이미지
chori
질문자

handleEnd 는 어떤 값인가요?

혹시 강의 끝까지 들으셧나요? 

강사님이 올려주신 교재에 나오는데 다시 확인해 봐주세용~~

네 감사합니다~

저는 코드 이상은 없어보이는데, 어느부분 때문에 작동이 안되는지가 궁금한거여서요!

단순히 기능만 작동하면 돼! 는 아닙니다ㅎ

chori님의 프로필 이미지
chori

작성한 질문수

질문하기