React_Map 사용시 'Unique Key Prop' 오류

Minji Jeong·2021년 9월 23일
2

React

목록 보기
3/9
post-thumbnail

React를 사용하여 인스타그램 클론코딩을 하던 중, 콘솔창에 다음과 같은 에러가 뜨는 것을 발견하였다.
정확히 어떤 부분에서 오류가 났는지 파악하기 어려웠고, 오류는 나지만 기능적인 부분에서 딱히 문제 되는 부분이 없어서 무시했다. 기능을 다 구현하고 코드 리팩토링을 하면서, 위 오류를 없애보기로 했다.

먼저 오류를 검색해보았더니 React에서 list를 사용할 때, 엘리먼트가 props로 key값을 가지고 있지 않아서 발생하는 문제였다.
처음에 작성한 코드를 보자.

List를 Map 함수로 하나씩 렌저링 하는 과정에서 발생한 오류

위 코드는 피드에 댓글을 추가하는 기능을 구현한 것이다.
state값인 commentList는 댓글 content가 들어가있는 배열이고,
map 함수를 사용하여 배열을 돌면서 Comment 컴포넌트를 하나씩 추가하는 코드이다.

React에서 형태가 같은 엘리먼트를 데이터만 바꿔서 여러개 찍어낼 때, 주로 map 함수를 이용하는데 이 부분에서 unique key prop 오류가 발생한 것이었다.

오류가 발생한 이유?

React의 가장 큰 장점은 필요한 부분만 렌더링 한다는 것이다.
리스트를 생성할 때도 마찬가지로 배열 전체를 렌더링하는 것이 아니라, 추가/수정/삭제된 부분만 계산해서 렌더링한다.

리스트 순서는 그대로, 컴포넌트만 추가되었을 때

첫번째와 두번째 엘리먼트 값은 같고 마지막에 새로운 엘리먼트가 추가된 경우, 변경된 부분은 맨 마지막 리스트 밖에 없기 때문에
그 부분만 렌더링 해주면 된다.

리스트 순서가 바뀌어 버린다면?

엘리먼트가 맨 끝이 아니라 맨 처음에 추가된 경우, 리스트 순서가 변경되어 버린다. 사실상 X와 Y값은 그대로인채 Z값만 추가된건데, 순서가 뒤바뀌니 React는 이를 인식하지 못하고 전체 리스트를 다시 렌더링 해버린다. 비효율적이라고 볼 수 있다.

key props 추가해주는 이유

이러한 비효율적인 문제를 해결하기 위해, React는 리스트 컴포넌트를 추가할 때 고유한 값을 가지는 key props를 필요로 한다. Key값을 통해 엘리먼트가 이미 존재하는지, 새로 추가 되었는지 판단하기 때문에 리스트 순서가 변경되어도 필요한 부분만 렌더링 할 수 있다.

Key props 추가하는 방법

각 list 엘리먼트에 key 값을 지정해주어야 한다.
오류가 발생했던 코드를 다음과 같이 수정했다.부모 컴포넌트에서 map 함수를 이용하여 자식 컴포넌트(list)를 불러올 때, key값으로 각 엘리먼트의 id값을 넘겨주었다.

key값을 배열 index로 지정하면 안됨!

처음에는 key값으로 배열의 index값을 지정해주었다. 가장 간편한 방법이라고 생각할 수 있지만 큰 오산이었다.
key값을 index로 지정해주면 위에서 봤던 코드와 마찬가지로, 리스트 순서가 바뀌어 버리면 인덱스 값도 바뀌게 되므로 전체를 렌더링 하게 되는 일이 발생한다.
항목의 순서가 바뀌지 않는다면 index로 지정해도 상관 없겠지만, 순서가 바뀔 우려가 있다면 각 list가 가지는 고유한 값(id값 등)을 key값으로 지정하는 것이 가장 좋다.

key값은 컴포넌트로 전달 되지 ❌않음❌

props로 key값이 잘 전달되었는지 확인해보고 싶어서, 자식 컴포넌트에서 전달된 props값을 찍어보려고 했다. 그런데 다음과 같은 오류가 발생하였다 👉 'key' is not a prop 컴포넌트를 출력해 보았을 때도 key값은 넘어오지 않았다.key값은 컴포넌트를 렌더링할 때 변경된 엘리먼트를 판별하기 위해 사용하는 값이기 때문에, 컴포넌트로 그 값을 전달하지는 않는다고 한다. 따라서 key값 처럼 고유한 값을 전달해야 될 때는, 다른 props를 생성해서 넘겨주어야 한다.

결과

최종적으로 key값을 잘 넘겨주었더니 unique key prop 오류가 사라졌고, 댓글도 정상적으로 추가되었다. 검색한 아이디를 필터링 하는 기능도, 똑같은 방법으로 에러를 해결하였다.
사실 복잡하지 않은 기능이라서 그런지, key값을 넘겨주지 않았다고 해도 기능적으로 큰 오류는 없었는데 성능적인 면을 고려하여 저런 에러를 띄워주는 것이 굉장히 유용하다고 생각했다.
(key값을 별도로 지정해주지 않으면 기본적으로 index값을 사용한다고 한다)

프론트엔드 개발을 하면서 보이는 것(UI, 기능 작동 등)에만 신경을 쓰다 보니, 성능적인 부분이나 라이브러리의 장점을 극대화하는 것에 대해서는 거의 고민을 해보지 않았다.
이번 기회를 통해서 효율적인 코드 짜기에 대해서 다시 한 번 생각해보게 되었고, 코드 리팩토링도 필수적으로 해야겠다고 생각하였다.
React를 이해하는 데에 많은 도움이 된 에러였다 💫

profile
쿼카를 사랑하는 프론트엔드 개발자입니다 :)

0개의 댓글