[React] map()으로 컴포넌트 호출시 key를 index로 두면 안되는 이유

해준박·2024년 3월 19일
0

react로 프로젝트를 진행 할 때, map()을 활용하여 중복된 컴포넌트를 여러 개 만들 수 있다.

{list.map((list, index) => (
        <div key={index}>
          {list.data}
          <input />
        </div>
))}

데이터에 유일한 id가 없다면, 보통 key값을 인덱스로 두는 경우가 가끔 있다.
하지만 이 방법은 별로 좋지 않다고 한다. 먼저 key의 역할을 보자


공식문서에서의 내용이다 어떤 항목을 변경, 추가 또는 삭제 할지 식별하는 것을 돕습니다 가 포인트다.
또한 공식문서를 조금 더 읽어보면

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

예시

import "./App.css";
import { useState } from "react";
function App() {
  const [list, setList] = useState([{ data: "A" }, { data: "B" }, { data: "C" }]);

  const clickAdd = () => {
    setList([{ data: "D" }, ...list]);
  };

  return (
    <>
      {list.map((list, index) => (
        <div key={index}>
          {list.data}
          <input />
        </div>
      ))}
      <input value={"D 추가"} type="button" onClick={clickAdd} />
    </>
  );
}

export default App;

key를 인덱스로 뒀을 때 D를 데이터를 추가 할 경우, 리렌더링 될 때 D는 key = index[0]이 되면서 입력되어있던 input의 value는 key=0이므로 D의 컴포넌트가 된다.

이러한 문제가 생기니 컴포넌트의 key값은 가급적 고유id를 사용해야한다고 한다.

고유 id 사용

import "./App.css";
import { useState } from "react";
function App() {
  const [list, setList] = useState([
    { data: "A", id: 11 },
    { data: "B", id: 12 },
    { data: "C", id: 13 },
  ]);

  const clickAdd = () => {
    setList([{ data: "D" }, ...list]);
  };

  return (
    <>
      {list.map((list, index) => (
        <div key={list.id}>
          {list.data}
          <input />
        </div>
      ))}
      <input value={"D 추가"} type="button" onClick={clickAdd} />
    </>
  );
}

export default App;

각 데이터에 id를 추가 후 key값을 id로 설정해줬다.

원하는대로 되는 모습

결론적으로는 key의 index 사용은 좋은방법이 아니며, 고유한 key를 사용해야한다.
만약 key에 사용할 유니크한 키가 없다면 라이브러리를 사용하는 방법도 있다고 한다.

index를 사용해야한다면 밑에 3가지를 모두! 만족해야한다.

  1. 배열과 각 요소가 static이며 computed 되지 않고 변하지 않아야 한다.
  2. 데이터 내부에 id로 쓸만한 unique 값이 없을 경우
  3. 데이터가 결코 reordered or filtered 되지 않을 경우
profile
기록하기

0개의 댓글