해결된 질문
작성
·
40
0
73강 7분 50초 내용입니다.
투두리스트 프로젝트의 List.jsx에서 TodoItem.jsx로 prop을 넘길 때 강의에서는
todos.map((todo) => {return (<TodoItem key={todo.id} {...todo} />;}
위 처럼 작성하고 있습니다.
저는 props를 spread syntax가 아닌 객체 자체로 한 번에 전달해보려고 아래와 같이 작성했습니다.
todos.map((todo) => {return <TodoItem key={todo.id} todo={todo} />;}
그런데 이렇게 작성하면 다음과 같은 에러가 발생합니다: Each child in a list should have a unique "key" prop.
todos 배열의 각 요소에는 고유한 id가 있다는 것을 확인했고, 동일한 코드에서 todo={todo}를 {...todo}로 변경하면 경고 없이 정상적으로 동작합니다.
저는 단순히 {...todo}는 객체 속성을 각각 개별 props로 넘기고, {todo}는 하나의 객체로 넘기는 차이만 있다고 생각했는데, 이 두 방식의 어떤 차이로 인해 이런 경고가 발생하는지 궁금합니다.
답변 2
0
안녕하세요 이정환입니다.
말씀하신 에러는 리스트로 렌더링되는 아이템 컴포넌트에 key 값이 설정되지 않았을때에만 발생하는 오류입니다. 따라서 Props의 전달 방식을 {...todo} 에서 todo={todo}로 변경한것과 큰 연관은 없어보입니다. 이상하네요 🤔
아마 중복된 키값이 설정되는 문제가 아닐까 싶은데요 ... 리액트 개발자 도구를 열어서, 혹시 key Prop이 정상적으로 각 아이템 컴포넌트에 매핑되는지 살펴보셔야 할 것 같습니다...!
0
안녕하세요, 인프런 AI 인턴입니다. 르르말님.
리액트에서 리스트를 렌더링할 때, 각 요소에 고유한 key
prop을 제공하는 것은 필수적입니다. todos.map
을 통해 TodoItem
컴포넌트를 생성할 때, key
값을 TodoItem
에 잘 전달하셨지만, 문제가 되는 부분은 key
의 위치입니다.
에러 메시지의 주 원인은 아래와 같은 차이에서 발생합니다:
Spread Syntax {…todo}:
{...todo}
를 사용하면 todo
객체의 모든 속성이 개별적인 props로 TodoItem
에 전달됩니다. 이 경우, key
는 TodoItem
에서 직접 전달되므로 정상적으로 작동합니다.Single Object Prop todo={todo}:
todo={todo}
를 사용하면 todo
객체가 단일 prop으로 전달됩니다. TodoItem
에서는 props.todo.key
가 아닌 props.key
로 key
값이 필요합니다. 따라서 이 설정에서는 key
prop이 실제로 TodoItem
에 전달되지 않습니다.리액트는 key
prop을 각 컴포넌트의 최상위 레벨에 직접 지정해 주어야 합니다. ...todo
를 사용하면 객체의 모든 속성을 풀어서 각각 별도로 props에 주기 때문에 key
속성도 별도로 전달할 수 있지만, todo={todo}
방식에서는 key
가 todo
객체 내부에 감춰지게 되어 TodoItem
의 최상위 레벨에서 key
를 직접 참조할 수 없게 되는 점이 문제의 원인이 됩니다.
이 문제는 TodoItem
컴포넌트를 선언할 때 props를 어떻게 처리하느냐에 따라 달라질 수도 있으니, key
를 직접 넘기지 않는 방식인 경우 React.PureComponent
나 React.memo
사용에도 유의하셔야 합니다.
이 점만 조정하시면 일반 객체로도 정상 작동 가능하니, 필요시 spread syntax
를 사용하는 것이 유지 보수성 및 코드 가독성 측면에서 유리합니다.
비슷한 질문이 있던 게시글은 아래를 참고해 주세요:
- 질문 제목: [리액트] props로 객체 전달 시 key prop 문제 및 해결법
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.