-
Notifications
You must be signed in to change notification settings - Fork 2
코드리뷰 내용중 index as a key in list
-
key
는 리액트가 어떤 아이템이 추가되고 변경되고 삭제되었는지를 알아채는데 도움을 준다. - 배열 내부 요소에 키를 지정하여 요소를 안정적으로 식별할 수 있어야한다.
-
key
를 지정하는 최고의 방법은 리스트의 아이템을 다른 아이템들 사이에서 유니트하게 식별할 수 있는 문자열로 지정하는 것이다. 대부분의 경우 아이템의 아이디를 데이터의key
로 사용한다. - 안정적인
id
가 없는 경우 대부분 리스트의 인덱스를key
로 사용할 수도 있다. 하지만 리스트의 아이템의 순서가 바뀔수도 있는 경우 인덱스를 키로 사용하는 것은 추천하지 않는다. - 이는 성능에 부정적인 영향을 줄 수 있으며 컴포넌트의
state
에 이슈를 발생할 수 있다. 자세한 내용은 다음 링크를 참조 [in-depth explanation on the negative impacts of using an index as a key.] - 만약 명백한 키를 리스트 아이템의 키로 지정하지 않으면 리액트는 기본적으로 인덱스를
key
로 지정한다.
아래는 Robin Pokorny의 index 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
를 생성하는것이 중복되어 피할 수 있는것은 사실입니다. 예를 들어 라이센스 조항 또는 기여자들의 목록 등. 결정을 돕기위해 이 예제가 공통적으로 갖는 세 가지 조건을 정리했습니다.
- 리스트와 각 아이템들은 정적입니다. 이것들은 계산되지 않으며 변경되지 않습니다.
- 리스트의 아이템들은
id
를 갖지 않습니다. - 목록은 다시 정렬되거나 필터링 되지 않습니다.
이러한 조건들이 모두 충족된다면 인덱스를 안전하게 key
로 사용할 수 있습니다.
여기는 잘 이해가 안됨;
이 기사에서는 React에 대해 글을 썼지 만 문제는 독점적이지 않습니다. Preact와 같은 유사한 라이브러리에서도 위험이 존재합니다. 그러나 효과가 다를 수 있습니다. 마지막 요소가 사라지는 다음 StackOverflow 질문을 참조하십시오. 또한 Preact의 작성자 인 Jason Miller.가 제공 한 답변에 설명되어 있습니다.