리액트 공식 문서 정리해보기 - 리스트에서 Key

이종호·2021년 4월 4일
1

React

목록 보기
1/5
post-thumbnail

요약

  1. React에서 자식 컴포넌트를 리스트로 만들 때 어떤 자식인지 수정되었는지 추적하기 위해 key 속성값을 지정해 줘야 한다.

  2. 배열의 값들의 순서가 바뀔 수 있다면(삭제나 순서 이동)배열의 인덱스를 key로 이용하면 원하지 않는 결과를 리턴한다.

  3. 이를 해결하기 위해 4가지 방법이 있다.

해결1. 부모 컴포넌트에서 글로벌 index를 만들어 부여하자.

해결2. UUID, uniqid같은 서드파티 라이브러리를 이용하자.

해결3. new Date.getTime() 를 이용하자.

해결4. 서버로 부터 값을 받아올 경우 id값을 가져오자.

아마 3번과 4번을 많이 이용할 것 같은데 성능을 위해서라면 1번이 좋겠지만, 실제 어떤 문제가 더 발생할지 모르겠다.

아래는 react공식 문서를 따라 적으면서 중요해 보이는 부분만 따로 빼내었다.


Key

Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다.
key는 엘리먼트에 안정적인 고유석을 부여하기 위해 배열 내부의 엘리먼트에 지정해야합니다.

Key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다.
대부분의 경우 데이터의 ID를 key로 합니다.

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 인덱스를 key로 사용할 수 있습니다.

항목의 순서가 바뀔 수 있는 경우 key에 인덱스를 사용하는 것은 권장하지 않습니다.
이로 인해 성능이 저하되거나 컴포넌트의 state와 관련된 문제가 발생할 수 있습니다.

상세 참고 사이트

상세 페이지 간추린 내용
1. Key는 React가 DOM요소를 식별하는 데 사용하는 유일한 것
2. 목록에 항목을 푸시하거나 중간에 항목을 제거하면 어떻게 되나?
3. 이전에 키로 사용한 객체를 다른 객체로 착각한다.
예제 사이트
1번째 객체에 값을 넣고 앞쪽에 add item을 하자 새로 추가된 배열에 이전 값이 들어가 있다.
인덱스는 배열에 추가된 요소의 위치를 나타내지 요소의 고유한 값이 아니기 때문이다.

해결 방법

1. 글로벌 인덱스를 통한 인덱스 부여

let todoCounter = 1;
const createNewTodo = (텍스트) => ({ 
  completed : false, 
  id : todoCounter ++, 
  text 
}

2. nanoid 라이브러리 사용 (현재 사용하지 말라고 명시되어 있음)

이는 ..


실제 어떻게 쓰나 github페이지를 보니 React는 render간 일관성이 보장되지 않기 때문에 차라리 index를 쓰라고 권장한다.

3. 그렇다면..?

그렇다면 무엇을 key로 사용해야하나?
stackoverflow는 이렇게 답했다.

  1. 서버로부터 데이터를 받는 경우 id값도 같이 받아와서 key로 사용한다.
  2. UUID, uniqid와 같은 서드파티 라이브러리를 사용한다.
  3. new Date.getTime()의 임의의 숫자에 특정 문자를 더한 값을 이용한다.

그 외에 고유한 값을 직접 생성하라는데 일단 내 머리속에선 괜찮은 방법이 생각나지 않기 때문에(글로벌 인덱스가 이런 경우인가..? 그럼 componentWillUnmount에 제거하는 구문을 추가로 넣어야 하나? 잘 모르겠다.)

profile
코딩은 해봐야 아는 것

0개의 댓글