Skip to content

코드리뷰 내용중 index as a key in list

Junho Lee edited this page Nov 30, 2019 · 1 revision
  • key 는 리액트가 어떤 아이템이 추가되고 변경되고 삭제되었는지를 알아채는데 도움을 준다.
  • 배열 내부 요소에 키를 지정하여 요소를 안정적으로 식별할 수 있어야한다.
  • key 를 지정하는 최고의 방법은 리스트의 아이템을 다른 아이템들 사이에서 유니트하게 식별할 수 있는 문자열로 지정하는 것이다. 대부분의 경우 아이템의 아이디를 데이터의 key 로 사용한다.
  • 안정적인 id 가 없는 경우 대부분 리스트의 인덱스를 key로 사용할 수도 있다. 하지만 리스트의 아이템의 순서가 바뀔수도 있는 경우 인덱스를 키로 사용하는 것은 추천하지 않는다.
  • 이는 성능에 부정적인 영향을 줄 수 있으며 컴포넌트의 state 에 이슈를 발생할 수 있다. 자세한 내용은 다음 링크를 참조 [in-depth explanation on the negative impacts of using an index as a key.]
  • 만약 명백한 키를 리스트 아이템의 키로 지정하지 않으면 리액트는 기본적으로 인덱스를 key 로 지정한다.

아래는 Robin Pokornyindex as a key is an anti-pattern 의 글을 번역했습니다.

개발자들이 리스트를 렌더링 할때 아이템의 키를 인덱스로 지정하는 것을 많이 봤었습니다.

{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

이는 꽤 괜찮아 보이고 warning 을 제거할 수 있습니다. (지금은 index를 key로 써도 warning을 표시해준다.) 여기서 위험은 무엇일까요?

이는 어플리케이션을 망가뜨리고 옳지않은 데이터를 보여줄 수도 있습니다.

설명하자면, 리액트는 오직 key 를 가지고 DOM Element를 식별합니다. 만약 리스트에 새로운 아이템을 추가하거나 중간에 하나를 제거한다면 어떻게 될까요? 만약 key 값이 이전과 같다면 리액트는 DOM Element가 이전과 같은 component 를 나타낸다고 간주합니다. 실제로는 다른 데이터를 나타내는데도 말이죠.

나은 방법

각 항목에는 영구적이고 유니크한 속성 값이 있는것이 좋습니다. 이상적으로는 아이템이 생성되는 순간에 할당되어야 합니다. 물론 저는 지금 id 에 대해 이야기하고 있습니다. 그래서 다음과 같이 쓸 수 있겠네요.

{todos.map((todo) =>
  <Todo {...todo}
    key={todo.id} />
)}

주의: 아이템이 이미 가지고 있는 값들 중 id 로 쓸만한 값이 있을지도 모릅니다.

이렇게 한다면 번호매기기를 추상화에서 한단꼐 위로 끌어올릴 수 있습니다. 글로벌한 인덱스를 사용한다면 어떠한 두 아이템도 서로 다른 id를 가질 수 있습니다.

todoCounter = 1;
function createNewTodo(text) {
  return {
    completed: false,
    id: todoCounter++,
    text
  }
}

더 나은 방법

id 를 생산하는 솔루션은 아이템들을 분산적으로 생산할 수 있는 더욱 강력한 접근법을 사용해야 합니다. 그래서 저는 shortid 를 추천합니다. 이는 순차적이지 않고 짧은 URL 친화적인 고유 id 를 빠르게 생성합니다. 코드는 다음과 같습니다.

var shortid = require('shortid');
function createNewTodo(text) {
  return {
    completed: false,
    id: shortid.generate(),
    text
  }
}

업데이트: 예외적인 규칙

많은 사람들이 정말 항상 id 를 생성해야 하냐고 묻습니다. 몇몇 다른사람들은 인덱스를 key 로 사용할 때 몇가지 유스케이스를 제안했습니다.

때때로 새로운 id 를 생성하는것이 중복되어 피할 수 있는것은 사실입니다. 예를 들어 라이센스 조항 또는 기여자들의 목록 등. 결정을 돕기위해 이 예제가 공통적으로 갖는 세 가지 조건을 정리했습니다.

  1. 리스트와 각 아이템들은 정적입니다. 이것들은 계산되지 않으며 변경되지 않습니다.
  2. 리스트의 아이템들은 id를 갖지 않습니다.
  3. 목록은 다시 정렬되거나 필터링 되지 않습니다.

이러한 조건들이 모두 충족된다면 인덱스를 안전하게 key 로 사용할 수 있습니다.

업데이트2: React, Preact, and *react

여기는 잘 이해가 안됨;

이 기사에서는 React에 대해 글을 썼지 만 문제는 독점적이지 않습니다. Preact와 같은 유사한 라이브러리에서도 위험이 존재합니다. 그러나 효과가 다를 수 있습니다. 마지막 요소가 사라지는 다음 StackOverflow 질문을 참조하십시오. 또한 Preact의 작성자 인 Jason Miller.가 제공 한 답변에 설명되어 있습니다.

1. 그라운드 룰

2. 스크럼 hackmd link

3. 변경 내역

4. 스프린트

5. 기술공유

6. 팀 회고록

Clone this wiki locally