0Pricing
React Academy · 강의

Key 및 Ref 모범 사례

안정적인 키를 사용하고 인덱스를 키로 사용할 때의 문제를 피하며 콜백 ref를 다룹니다.

Key 및 Ref 모범 사례은(는) CoddyKit의 무료 React Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

환영합니다

이 레슨에서는 목록 키를 올바르게 사용하는 방법, 배열 인덱스를 키로 사용하면 버그가 발생하는 이유, 콜백 참조와 전달된 참조를 다루는 방법을 배웁니다.

키가 중요한 이유

React는 `key` 프롭을 사용해 렌더링 사이에 목록에서 어떤 항목이 변경되거나 추가되거나 제거되었는지 추적합니다. 올바른 키를 사용하면 React가 기존 DOM 노드를 재사용할 수 있지만, 잘못된 키를 사용하면 불필요한 마운트 해제와 재마운트가 발생합니다.

안정적이고 고유한 키

가장 좋은 키는 데이터에 포함된 안정적이고 고유한 ID입니다. 예를 들면 데이터베이스 행 ID나 UUID가 있습니다. 이 키는 전체 페이지에서 전역적으로 고유할 필요 없이 형제 항목 사이에서만 고유하면 됩니다.
users.map(user => (
  <UserCard key={user.id} user={user} />
))

인덱스를 키로 사용하면 문제가 되는 이유

배열 인덱스를 키로 사용하는 방식은 정적인 목록에서는 잘 작동하지만, 정렬되거나 필터링되는 목록에서는 버그를 일으킵니다. 항목의 순서가 바뀌면 React는 인덱스를 기준으로 컴포넌트를 연결하고 잘못된 DOM 노드를 재사용하므로 입력값과 애니메이션 상태가 손상됩니다.
// Risky when list can reorder or filter
items.map((item, i) => <Row key={i} {...item} />)

인덱스 키를 사용해도 되는 경우

인덱스를 키로 사용하는 방식은 다음 조건을 모두 만족할 때만 허용됩니다. (1) 목록이 재정렬되거나 필터링되지 않고, (2) 항목에 안정적인 ID가 없으며, (3) 항목에 로컬 상태가 없어야 합니다(예: 입력값). 정적인 표시 목록에는 사용해도 됩니다.

안정적인 ID 생성

데이터에 ID가 없다면 렌더링 중이 아니라 항목을 생성할 때 ID를 생성하십시오. `crypto.randomUUID()` 또는 `nanoid` 라이브러리를 사용할 수 있습니다.
const newItem = { id: crypto.randomUUID(), text: 'Buy milk' };

useRef 기초

`useRef`는 렌더링 사이에 값이 유지되면서도 다시 렌더링을 일으키지 않는 변경 가능한 객체를 반환합니다. DOM 참조와 타이머 ID 같은 변경 가능한 값을 보관하는 데 사용합니다.
const inputRef = useRef(null);
<input ref={inputRef} />
// Access DOM node: inputRef.current.focus();

콜백 참조

참조 객체를 전달하는 대신 **콜백 참조**를 전달할 수 있습니다. 콜백 참조는 DOM 노드가 마운트될 때 React가 해당 노드와 함께 호출하고, 마운트가 해제될 때 `null`과 함께 호출하는 함수입니다. 이를 통해 노드를 사용할 수 있게 되는 즉시 로직을 설정할 수 있습니다.
function Input() {
  return (
    <input
      ref={node => {
        if (node) node.focus();
      }}
    />
  );
}

컴포넌트 참조에 forwardRef 사용하기

함수 컴포넌트는 일반 프롭으로 `ref`를 받지 않습니다. 컴포넌트를 `React.forwardRef`로 감싸면 부모 컴포넌트가 내부 DOM 노드에 참조를 연결할 수 있습니다.
const FancyInput = React.forwardRef((props, ref) => (
  <input ref={ref} className="fancy" {...props} />
));

// Parent
const inputRef = useRef(null);
<FancyInput ref={inputRef} />

useImperativeHandle

부모가 자식에 대한 참조를 보유하고 있을 때는 `useImperativeHandle`을 사용해 자식이 외부에 노출하는 내용을 정확히 제어할 수 있습니다. 이렇게 하면 자식의 내부 DOM은 비공개로 유지하면서 깔끔한 명령형 API를 제공할 수 있습니다.
const Child = forwardRef((_, ref) => {
  const innerRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => innerRef.current.focus(),
  }));
  return <input ref={innerRef} />;
});

빠른 확인

재정렬될 수 있는 목록에서 배열 인덱스를 키로 사용하면 안 되는 이유는 무엇인가요?

복습

안정적인 데이터 ID를 키로 사용하고, 동적인 목록에서는 인덱스 키를 피하고, DOM 접근과 변경 가능한 값에는 useRef를 사용하고, 마운트 및 마운트 해제 로직에는 콜백 참조를 사용하고, 자식 컴포넌트에서 참조를 노출하려면 forwardRef를 사용하십시오.

다음 학습

다음 레슨: **폴더 구조 및 이름 지정 규칙** — 기능을 기준으로 폴더를 구성하고 일관된 파일 이름을 사용해 React 프로젝트를 정리합니다.

자주 묻는 질문

“Key 및 Ref 모범 사례” 강의는 무료인가요?

네 — “Key 및 Ref 모범 사례” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Academy 강의 전체를 잠금 해제할 수 있습니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Key 및 Ref 모범 사례”에서 뭘 배우나요?

안정적인 키를 사용하고 인덱스를 키로 사용할 때의 문제를 피하며 콜백 ref를 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 React Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“Key 및 Ref 모범 사례” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. StrictMode의 역할
  2. 순수 구성 요소 및 렌더링 부작용 피하기
  3. Key 및 Ref 모범 사례
  4. 폴더 구조 및 이름 지정 규칙
← React Academy(으)로 돌아가기