인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

qmwneaaa님의 프로필 이미지
qmwneaaa

작성한 질문수

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

List 컴포넌트 생성하기

'List 컴포넌트 생성하기' 따라하다가 에러가 발생했습니다

작성

·

310

0

List.js로 나눈 다음 data. 도 지우고 했는데 List.js에서 key={id} 부분에서 계속 오류가 발생합니다.

List.js:22 Uncaught TypeError: Cannot read properties of undefined (reading 'draggableProps')

at List (List.js:22:1)

at renderWithHooks (react-dom.development.js:16305:1)

at mountIndeterminateComponent (react-dom.development.js:20074:1)

at beginWork (react-dom.development.js:21587:1)

at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)

at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)

at invokeGuardedCallback (react-dom.development.js:4277:1)

at beginWork$1 (react-dom.development.js:27451:1)

at performUnitOfWork (react-dom.development.js:26557:1)

at workLoopSync (react-dom.development.js:26466:1)

 

Lists.js 코드

import React from 'react';
import { DragDropContext } from "react-beautiful-dnd";
import { Droppable } from "react-beautiful-dnd";
import { Draggable } from "react-beautiful-dnd";
import List from "./List";

export default function Lists({todoData, setTodoData}) {

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

        const [reorderedItem] = newTodoData.splice(result.source.index, 1);
        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) => (
                                        <List
                                            key={data.id}
                                            id={data.id}
                                            title={data.title}
                                            completed={data.completed}
                                            todoData={todoData}
                                            setTodoData={setTodoData}
                                            provided={provided}
                                            snapshot={snapshot}
                                        />
                                    )}
                                </Draggable>
                            ))}
                            {provided.placeholder}
                        </div>
                    )}
                </Droppable>
            </DragDropContext>
        </div>
    );
}

 

List.js 코드

import React from "react";

const List = ({
    id, title, completed, todoData, setTodoData, provided, snapshot
}) => {
    const handleClick = (id) => {
        let newTodoData = todoData.filter((data) => data.id !== id);
        setTodoData(newTodoData);
    };

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

    return (
        <div key={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" 
                       onChange={() => handleCompleteChange(id)} 
                       checked={completed}
                />
                <span className={completed ? 'line-through' : undefined}>
                    {title}
                </span>
            </div>
            <div className='items-center'>
                <button 
                    className="px-4 py-2 float-right"
                    onClick={() => handleClick(id)}>
                    X
                </button>
            </div>
        </div>
    )
}

export default List;

답변 2

0

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

안녕하세요 ~

혹시 index.js에 있는 Strictmode 지우셨나요~ ?

그 부분이 있다면 지우고 한번 시도해주세요 ~

0

안녕하세요, 인프런 AI 인턴입니다.

List.js에서 발생한 오류에 대해 말씀해 주셨네요. 에러 메시지 “Cannot read properties of undefined (reading ‘draggableProps’)“는 List 컴포넌트에 전달해야 할 provided 객체가 undefined임을 나타냅니다. 이는 Draggable 컴포넌트에서 providedList 컴포넌트로 제대로 전달하지 않았거나, 문제가 있는 탓일 수 있습니다.

주신 Lists.js의 코드를 보면 Draggable 컴포넌트는 함수형 컴포넌트의 형태로 providedsnapshot를 인자로 받아 List 컴포넌트로 전달하고 있습니다. 코드 상에 문제가 있는 부분을 찾지 못했으므로, 앞서 문제를 해결하기 위해 몇 가지 점검해 보아야 할 점이 있습니다.

  1. Draggable와 Droppable 라이브러리 임포트 확인: react-beautiful-dnd 라이브러리가 올바르게 설치되어 있고, 임포트 문제가 없는지 확인해 주세요.

  2. 컴포넌트 트리 확인: DragDropContext > Droppable > Draggable > List 구조로 컴포넌트가 올바르게 중첩되어 있는지 확인해 주세요.

  3. Draggable 컴포넌트에서 key가 유니크한 값인지 확인: Draggable 컴포넌트의 key 속성에 전달된 data.id가 각 항목별로 유니크한지 확인해 보세요.

  4. State 업데이트 방식 점검: handleEnd에서 todoData를 직접 수정하는 것이 리액트의 state 업데이트 원칙에 어긋나지 않는지 확인해 주세요. 바람직한 방법은 Immutable한 방식으로 새로운 배열을 생성하여 업데이트하는 것입니다.

  5. Props 전달 확인: List 컴포넌트로 전달되는 providedsnapshot 객체가 Draggable 컴포넌트 내부에서 제대로 정의되어 있는지 확인해 보세요. 컴포넌트의 프로퍼티를 디버깅하거나 콘솔로 출력하여 정상적으로 전달되는지 확인할 수 있습니다.

  6. 리액트 개발자 도구 사용: 리액트 개발자 도구를 사용하여 런타임에서 List 컴포넌트로 전달된 props를 직접 확인해 보세요.

위 점검 사항들을 통해 문제를 해결하시길 바랍니다. 만약 여전히 같은 문제가 발생한다면, 콘솔 출력, 디버거 사용 또는 리액트 개발자 도구를 통해 추가적인 디버깅을 진행해 보시기 바랍니다.

qmwneaaa님의 프로필 이미지
qmwneaaa

작성한 질문수

질문하기