6장. 컴포넌트 반복
Deep Dive - React 배열 index를 key로 사용하면 안되는 이유
map() 함수를 사용할 때 key 값으로 index를 자주 사용한다.
그러나, 공식문서에서는 key 값으로 index 사용을 권장하지 않는다.
왜 key를 사용해야하는가?
리액트에서 key는 어떤 원소에 변동이 있었는지 알기 위해 사용한다.
Virtual DOM을 비교하는 과정에서 key를 이용하여 정확하고 빠르게 변화를 추론하고 DOM 트리를 올바르게 업데이트하는 데 도움을 준다.
그런데 왜 index를 사용하면 안되는가?
미묘하고 복잡한 버그가 생길 수 있다.
import React, { useEffect, useState } from "react";
const Example = () => {
const [list, setList] = useState([
{ name: "철수" },
{ name: "영희" },
{ name: "민수" },
]);
const addItem = () => {
setList([{ name: "정국" }, ...list]);
};
const delItem = () => {
setList(list.filter((l) => l.name != "철수"));
};
return (
<>
{/* 추가 버튼과 삭제 버튼*/}
<input type="button" value="추가" onClick={addItem} />
<input type="button" value="삭제" onClick={delItem} />
<h2> Show Problem Example</h2>
{list.map((v, index) => (
<div key={index}>
{v.name}, idx: {index} <input type="text" />
</div>
))}
</>
);
};
export default Example;
key의 규칙
- key는 형제 간에 고유한다. 그러나 다른 배열의 JSX 노드에 동일한 키를 사용하는 것은 OK
- key는 변경되어서는 안 된다.
- 렌더링하는 동안 key를 생성하면 안 된다.
어떤 데이터가 key로 적합한가?
List 데이터에서 유니크한 값을 key로 사용해야한다.
-
데이터베이스의 데이터: 데이터가 데이터베이스에서 오는 경우 본질적으로 고유한 데이터베이스 키/ID를 사용
-
로컬에서 생성된 데이터: 데이터가 로컬에서 생성되고 유지되는 경우 항목을 생성할 때 처럼 증분 카운터나 메소드를 사용
- crypto.randomUUID()
- shorid
var shortid = require("shortid"); function createNewTodo(text) { return { id: shortid.generate(), text, }; }
배열 index를 key로 사용할 수 있는 경우?
- 배열과 각 요소가 static이며 computed 되지 않고 변하지 않아야 한다.
- 데이터 내부에 id로 쓸만한 unique 값이 없을 경우
- 데이터가 결코 reordered or filtered 되지 않을 경우
요약
Q. A. react에서 key는 Virtual DOM을 비교하는 과정에서 정확하고 빠르게 변화를 추론하고 올바르게 업데이트하기 위해서 사용해야합니다. key를 사용할 때 주의해야할 점은 고유한 값을 사용해야한다는 것이고, 그렇기 때문에 배열의 index를 key로 사용하는 것은 지양해야합니다. 배열의 요소가 추가되거나 삭제되면 index의 값도 변동이 생겨 버그가 발생할수도 있기때문입니다.