[React] key 제대로 알고 사용하기

Sara Jo·2024년 12월 7일
0
post-thumbnail

React로 리스트를 렌더링할 때 key라는 속성을 매번 사용하고 있으면서도 왜 key를 사용하는지, key가 없으면 어떤 문제가 발생하는지 명확히 이해하지 못한 채 사용하고 있었다.. 얼마 전 key를 이용해 버그를 해결한 경험이 있어서 이번 기회에 key 의 개념, 역할, 사용법에 대해 제대로 공부하고 넘어가고자 한다!

🚀 React에서 key란 무엇인가?

keyReact가 리스트의 각 항목을 구분하는 유일한 식별자이다. React는 UI를 효율적으로 업데이트하기 위해 Virtual DOM을 사용하고, 변경 사항을 감지하여 실제 DOM을 업데이트한다. 이 과정에서 keyReact가 어떤 항목이 추가, 삭제 혹은 수정되었는지 빠르게 파악하도록 도와주는 중요한 역할을 한다.

React 공식 문서에는 key에 대해 아래와 같이 설명하고 있다.

🚨 왜 React는 key가 필요할까?

여러분의 컴퓨터 바탕화면에 파일 이름이 없다고 상상해 보세요. 파일을 이름이 아닌 순서로만 구분해야 한다면, 이렇게 말해야겠죠: 첫 번째 파일, 두 번째 파일, 세 번째 파일

그런데 파일 하나를 삭제하면 어떻게 될까요?
두 번째 파일이 첫 번째 파일이 되고, 세 번째 파일이 두 번째 파일이 되는 식으로 순서가 계속 꼬이게 될 거예요.

React에서 key는 바로 파일 이름과 같은 역할을 합니다. key는 항목이 리스트 내에서 고유하게 식별되도록 도와줍니다. 파일 이름이 순서가 바뀌어도 항목을 정확히 식별할 수 있듯이, key가 있으면 리스트의 항목이 삭제되거나 재정렬되더라도 React가 어떤 항목인지 파악할 수 있어요.

key가 없는 경우 React는 각 항목을 구분할 수 없기 때문에 리스트가 변경될 때 어떤 항목이 변경되었는지 정확히 알 수 없게 되고, 이는 성능 저하와 예상치 못한 UI 버그를 발생시킬 수 있다.


📋 key를 사용한 리스트 렌더링

keyReact에서 리스트를 렌더링 할 때 가장 많이 사용된다. 이 때 key배열의 각 항목을 유일하게 식별할 수 있는 값으로 설정해야 한다.

1️⃣ id를 key로 사용하기

const fruits = [
  { id: 1, name: '사과' },
  { id: 2, name: '바나나' },
  { id: 3, name: '오렌지' }
];

function ItemList() {
  return (
    <ul>
      {fruits.map((fruit) => (
        <li key={fruit.id}>{fruit.name}</li> // id를 key로 사용
      ))}
    </ul>
  );
}

2️⃣ index를 key로 사용하기

indexkey로 사용할 수도 있지만, 항목의 순서가 변경되거나 추가/삭제될 경우 문제가 발생할 수 있다. indexkey로 사용할 때는 항목이 고정적이고 순서가 바뀌지 않는 경우에만 사용해야 한다.

const items = ['사과', '바나나', '오렌지'];

function ItemList() {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li> // index를 key로 사용
      ))}
    </ul>
  );
}

React 공식 문서에서도 아래와 같이 index를 key로 사용할때 주의해야 할 점을 설명하고 있다.

⚠️ Key를 사용할 때 주의할 점

  • React는 key를 지정하지 않으면 배열의 index를 자동으로 key로 사용합니다. 하지만 배열의 항목이 추가되거나 삭제되거나 순서가 바뀌면 index가 변하게 되고, 이로 인해 React가 항목을 잘못 추적할 수 있으며 결과적으로 UI 버그가 발생할 수 있어요.
  • Math.random() 같은 동적 값으로 key를 생성하지 마세요. key를 Math.random()처럼 매 렌더링마다 바뀌는 값으로 설정하면 React가 매번 새로운 항목으로 인식하게 되고, 컴포넌트와 DOM이 매번 재생성되어 성능 저하 발생하게 되며 입력 필드와 같은 사용자 입력값이 초기화됩니다.
  • 안정적인 ID를 사용하세요. 데이터에 기반한 안정적인 ID를 key로 사용하는 것이 가장 좋은 방법입니다. 예를 들어, 항목에 고유한 id가 있다면 이를 key로 지정하세요.
<Profile key={user.id} userId={user.id} />

🔄 컴포넌트 초기화 및 리렌더링

key는 주로 리스트를 렌더링할 때 사용되지만, 다른 상황에서도 사용될 수 있다. 그 중 하나가 컴포넌트 초기화 혹은 강제 리렌더링이 필요한 경우이다.

React에서는 같은 컴포넌트를 다시 렌더링할 때 기존 상태를 유지하려는 특성이 있다. 하지만 때로는 상태를 초기화하고 강제로 새로 렌더링해야 할 때가 있다. 이럴 때 key를 변경하면 React는 해당 컴포넌트를 완전히 새롭게 인식하게 되고, 리렌더링한다.

예를 들어, 폼 컴포넌트를 다시 초기화해야 할때 key를 활용할 수 있다. 아래의 예시 코드에서 formKey 값이 변하면 <Form /> 컴포넌트의 key가 바뀌게 된다. React는 이전 Form 컴포넌트를 제거하고 새 Form 컴포넌트를 렌더링하면서 상태가 초기화된다.

import { useState } from 'react';

function ResettableForm() {
  const [formKey, setFormKey] = useState(0);

  const resetForm = () => {
    setFormKey((prevKey) => prevKey + 1); // key 값을 변경
  };

  return (
    <div>
      <Form key={formKey} />
      <button onClick={resetForm}>Reset Form</button>
    </div>
  );
}

function Form() {
  const [name, setName] = useState('');

  return (
    <input
      type="text"
      value={name}
      onChange={(e) => setName(e.target.value)}
      placeholder="이름을 입력하세요"
    />
  );
}

🎯요약

React에서 key는 리스트의 안정적인 렌더링과 컴포넌트의 올바른 초기화를 책임지는 중요한 요소이다.

  • 리스트 렌더링 시 항목의 IDkey로 사용하는 것이 가장 좋고, index는 항목이 고정적이고 순서가 바뀌지 않는 경우에만 사용하자.
  • 특정 상황에서는 key 값을 변경해 강제로 리렌더링을 수행할 수 있다.

0개의 댓글