tech.junha.kr

노트/React

map으로 랜더링 하려면 key를 사용해야한다

작성

0. key란?

  • 배열을 랜더링할 때 각각을 유니크하게 식별하기 위한 값이다.
  • DOM 요소들을 변경, 추가, 삭제할 때 효율적으로 diffing하기 위해서 반드시 필요하다.

1. 예시

function App() {
  const tart = ['딸기', '무화과', '치즈']

  return (
    <div className="App">
      {tart.map((item, index) => (
        <div key={index}>{`${item} 타르트`}</div>
      ))}
    </div>
  )
}

export default App;

2. key의 조건

  • key는 형제 사이에서 고유하기만 하면 된다.
  • 전체 범위에서 고유할 필요는 없으니, 두 개의 다른 배열을 만들 때 동일한 key를 사용할 수 있다.

3. 그렇다면 key에는 무슨 값을 줘야 하나요?

  • map의 index를 key로 사용할 수 있지만, 배열의 요소가 CRUD되는 상황에서 혼란의 여지가 많으니 권장하지 않는다.
  • 따라서 배열의 요소에 id 값이 있는 경우 id 값으로 key로 주는 방법이 가장 좋다.
const tart = [{id:1, name:"딸기"}, {id:2, name:"포도"}, {id:3, name:"무화과"}] 

const tart_array = tart.map((item)=>{
  return <div key={item.id}>{`${item.name} 타르트`}</div>
})

4. id값이 없으면 어떡하죠?

  • 각 배열의 요소가 중복 없이 고유한 값을 가진다는 조건이 있다면, 그 값을 key로 줄 수 있다.
const tart = ["딸기", "무화과", "치즈"]

const tart_array = tart.map((item)=>{
  return <div key={item}>{`${item} 타르트`}</div>
})

5. 다소 멍청한 방법이지만

  • 배열의 요소가 바뀔 때 마다 다시 전체 요소를 맵핑하여 고유한 key를 줄 수 있다. 하지만 연산엔 불리하다.
const newTart = tart.map((item) => {
    const newItem = { id: index, name: item };
    return newItem;
});

const tart_array = newTart.map((item)=>{
  return <div key={item.id}>{`${item.name} 타르트`}</div>
})

6. nanoid 패키지를 통한 id값 전달

  • id 값이 없는 배열의 형태라면, nanoid 패키지를 통해 key값을 고유하게 생성할 수 있다.
  • 하지만 매번 nanoid()를 실행해야 하기 때문에 연산적인 측면에서 역시 불리하다.
const createNewTodo = (text) => ({
  completed: false,
  id: nanoid(),
  text
}