Key Warning

  • key warning 메세지는 왜 발생할까?
  • 리액트는 데이터의 목록을 렌더링하는데 있어서 특별한 개념을 갖는다.
  • 이 개념은 리액트가 발생할 수 있는 어떤 성능 손실이나 버그없이 효과적으로 그런 목록들을 업데이트하고 렌더링할 수 있도록 보장하기 위해 존재한다.

key props를 쓰지 않았을때의 문제점

리액트는 새로운 아이템을 추가했을때 마지막 아이템으로 렌더링하고 모든 아이템을 업데이트해서 컨텐츠를 교체한다.

key props없이 배열을 추가해서 렌더링하면 생기는 일.

  1. 추가로 div를 넣어 렌더링해서 끝부분에 넣는다.
  2. 이후 모든 아이템들을 지나면서 배열에 있는 컨텐츠와 다시 일치시키기 위해 안에 있는 컨텐츠를 업데이트한다.

→ 성능 측면에서 최악 + 버그까지 발생 가능!!!

왜냐면 모든 목록을 체크해서 업데이트 해야하며 버그를 만들 수 있다.

어떤 버그?

만약 추가한 div가 stateful한 컴포넌트였다면 새로운 아이템이 이전 아이템을 덮어쓴다.

이러면 바뀌기 전의 아이템이 가지던 상태변화는 사라진다.

왜 리액트는 이렇게 작동하지?

다른 방법이 없기 때문이다.

간단히 배열의 길이를 체크하고 이미 렌더링된 아이템의 수만 확인한다.

리액트는 새로운 아이템이 어느 위치에 추가되어야하는지 모른다.

그래서 key props를 사용함으로써 어디에 새로운 아이템이 추가되어야 하는지 알려줄 수 있다.

key props

  • 리액트가 개별 아이템을 인식할 수 있도록 도와준다.
  • 목록의 아이템별로 고유값(key)를 설정한다.
  • key 값을 설정하면 리액트는 아이템을 식별할 수 있고, 배열의 길이 뿐만아니라 아이템이 위치해야할 곳까지 인식한다.
  • key는 배열 안에서 형제 사이에서 고유해야하고 전역에서는 고유할 필요 없다.
  • 보통 key값은 DB에서 데이터를 받아와서 map이나 reduce로 생성하기에 DB에서 보내준 id 값으로 보통 key값을 설정한다.

리액트 공식문서에서의 key 설명

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

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

Robin Pokorny’s가 작성한 글인 인덱스를 key로 사용할 경우 부정적인 영향에 대한 상세 설명을 참고하시길 바랍니다. 리스트 항목에 명시적으로 key를 지정하지 않으면 React는 기본적으로 인덱스를 key로 사용합니다.

더 자세히 알고 싶다면 왜 key가 필요한가에 대한 더 자세한 설명을 읽어보세요.

key는 반드시 변하지 않고, 예상 가능하며, 유일해야 합니다. 변하는 key(Math.random()으로 생성된 값 등)를 사용하면 많은 컴포넌트 인스턴스와 DOM 노드를 불필요하게 재생성하여 성능이 나빠지거나 자식 컴포넌트의 state가 유실될 수 있습니다.

Key로 인덱스를 사용할 경우 부정적인 영향

먼저 Key는 React가 DOM요소를 식별하는데 사용하는 유일한 것이다.

Key가 배열을 조작하기 전과 동일하면 React는 DOM 요소가 이전과 동일한 구성요소를 나타낸다고 가정한다.

Key는 렌더링 간에 변경되지 않는 안정적인 식별자여야 하지만 Index는 반드시 안정적일 수 없고 배열의 요소 순서가 변경될 때 바뀔 수 있기 때문에 Index를 사용한 Key는 안정적이지 않은 식별자이다.

고로 필자는 Hash를 이용해서 안정적인 키를 생성한다.

function stableHash(value) {
let hash = 0;
for (let i = 0; i < value.length; i++) {
hash = ((hash << 5) - hash) + value.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return hash;
}

function MyList() {
return (
<ul>
{items.map((item, index) => (
<li key={stableHash(`${index}-${item}`)}>{item}</li>
))}
</ul>
);
}

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response