2026. 7. 9.

React key warning이 보이면 전체 재작성 말고 map 안의 id부터 보세요

React 목록에서 key warning이 보이면 화면 전체를 다시 만들기보다 map 안의 반복 JSX와 안정적인 id부터 확인해야 합니다. index key를 써도 되는 조건, Math.random key가 위험한 이유, 삭제와 정렬 테스트까지 초보자 기준으로 정리합니다.

4 min read
React key warning이 보이면 전체 재작성 말고 map 안의 id부터 보세요 대표 이미지

AI가 만든 React 화면에서 목록은 보이는데 콘솔에 Each child in a list should have a unique key prop 경고가 뜰 때가 있습니다. 초보자는 이 경고를 보고 "화면은 나오니까 무시해도 되나" 또는 "AI에게 전체를 다시 만들라고 해야 하나"로 갈라집니다. 먼저 할 일은 둘 다 아닙니다. 전체 컴포넌트가 아니라 map() 안의 반복 JSX 한 줄부터 봅니다.

React 목록 화면과 콘솔 key warning을 함께 보며 map 안의 key 줄을 확인하는 작업 장면

React 공식 문서의 Rendering Lists는 배열을 JSX 목록으로 만들 때 각 항목에 key가 필요하다고 설명합니다. key는 React가 항목의 추가, 삭제, 정렬 뒤에도 같은 항목을 알아보게 하는 힌트입니다. 그래서 이 문제는 단순한 콘솔 정리가 아닙니다. 목록 항목의 신분증을 무엇으로 줄지 정하는 문제입니다.

warning을 지우기 전에 map 위치부터 찾습니다

가장 흔한 코드는 이런 모양입니다.

function TodoList({ todos }: { todos: Todo[] }) {
  return (
    <ul>
      {todos.map((todo) => (
        <li>{todo.title}</li>
      ))}
    </ul>
  );
}

경고가 뜨면 AI에게 "React 오류 고쳐 줘"라고 보내기 전에 map() 안에서 바로 반복되는 JSX를 찾습니다. 위 코드에서는 <li>가 반복 항목입니다. 이 항목에 안정적인 key를 붙입니다.

function TodoList({ todos }: { todos: Todo[] }) {
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}

여기서 핵심은 아무 값이나 넣는 것이 아니라 안정적인 key를 넣는 것입니다. 데이터에 id, slug, uuid처럼 항목을 구분하는 값이 있으면 그 값을 먼저 씁니다. 서버나 데이터베이스에서 받은 목록이라면 보통 이미 id가 있습니다. 로컬에서 새 항목을 만드는 기능이라면 항목을 만들 때 id를 저장한 뒤 그 id를 key로 씁니다.

이 문제는 React state 직접 수정으로 화면이 멈추는 상황과 같이 보면 더 이해하기 쉽습니다. key는 항목을 알아보는 기준이고, 배열 state 업데이트는 바뀐 목록을 React가 다시 계산하게 만드는 기준입니다. 둘 중 하나가 흔들리면 화면에 남은 입력값이나 체크 상태가 이상한 줄에 붙을 수 있습니다.

index key는 삭제와 정렬이 있는 목록에서 먼저 의심합니다

AI가 경고를 빨리 없애려고 이런 코드를 제안할 수 있습니다.

{todos.map((todo, index) => (
  <li key={index}>{todo.title}</li>
))}

이 코드는 경고를 없앨 수 있습니다. 하지만 항목을 삭제하거나 정렬하면 index가 다시 매겨집니다. 예를 들어 두 번째 항목을 삭제하면 세 번째 항목이 두 번째 index를 갖습니다. React 입장에서는 같은 자리의 같은 항목처럼 보일 수 있어서 입력값, 체크 상태, 펼침 상태가 다른 항목에 붙어 보이는 문제가 생깁니다.

id key와 index key가 삭제 후 입력값 유지에서 어떻게 달라지는지 비교한 다이어그램

index key가 항상 금지는 아닙니다. 목록이 고정되어 있고 추가, 삭제, 정렬이 없고 항목 안에 입력 상태도 없다면 문제가 드러나지 않을 수 있습니다. 다만 AI 코딩으로 만든 화면은 처음에는 고정 목록처럼 보여도 나중에 삭제, 필터, 정렬, 입력 기능이 붙는 경우가 많습니다. 그래서 초보자 기준은 간단합니다.

목록에서 항목을 삭제하나요? id key를 씁니다.
목록을 정렬하거나 필터하나요? id key를 씁니다.
목록 안에 input, checkbox, select가 있나요? id key를 씁니다.
서버나 DB에서 온 데이터에 id가 있나요? 그 id를 씁니다.

React 버튼이 눌러도 반응하지 않을 때 보는 순서처럼 이번에도 문제를 좁히는 것이 중요합니다. key warning은 화면 전체를 새로 만들 신호가 아니라 반복 항목의 식별값을 확인하라는 신호에 가깝습니다.

Math.random key는 경고를 숨기지만 항목을 계속 새로 만듭니다

더 위험한 임시 수정은 이런 코드입니다.

{todos.map((todo) => (
  <li key={Math.random()}>{todo.title}</li>
))}

이 코드는 key가 있으니 경고가 사라질 수 있습니다. 하지만 렌더링할 때마다 key가 바뀝니다. React 공식 문서는 렌더링 중에 key를 새로 만들면 key가 서로 맞지 않아 컴포넌트와 DOM이 매번 다시 만들어질 수 있고, 목록 안의 사용자 입력이 사라질 수 있다고 설명합니다.

Math.random(), Date.now(), 렌더링 중 바로 호출하는 crypto.randomUUID()는 피합니다. crypto.randomUUID()를 써야 한다면 항목을 처음 만들 때 id 필드로 저장해야 합니다.

function addTodo(title: string) {
  setTodos((prev) => [
    ...prev,
    { id: crypto.randomUUID(), title }
  ]);
}

{todos.map((todo) => (
  <li key={todo.id}>{todo.title}</li>
))}

AI에게는 "key 넣어 줘"라고만 말하지 말고, 데이터의 안정적인 id를 key로 쓰고 렌더링 중 random key를 만들지 말라고 말해야 합니다. 그래야 경고만 숨기는 임시 수정이 아니라 나중에 기능이 붙어도 버티는 수정이 나옵니다.

배열 state까지 같이 확인해야 수정이 끝납니다

key가 맞아도 배열 state를 직접 고치고 있으면 화면이 다시 꼬일 수 있습니다. React 공식 문서의 Updating Arrays in State는 state 안의 배열을 직접 바꾸지 말고 새 배열을 만들어 설정하라고 안내합니다. MDN의 Array.prototype.map 문서map()이 호출 결과로 새 배열을 만든다고 설명합니다.

삭제 기능은 이런 모양이 안전합니다.

function removeTodo(id: string) {
  setTodos((prev) => prev.filter((todo) => todo.id !== id));
}

수정 기능은 이런 모양으로 항목 하나만 새 객체로 바꿉니다.

function renameTodo(id: string, nextTitle: string) {
  setTodos((prev) =>
    prev.map((todo) =>
      todo.id === id ? { ...todo, title: nextTitle } : todo
    )
  );
}
React key warning 수정 뒤 map 위치, 안정 id, random 금지, 삭제 정렬 테스트를 확인하는 체크리스트

수정 뒤에는 아래 네 가지를 직접 눌러 봅니다.

1. 목록 안 input에 서로 다른 값을 입력합니다.
2. 가운데 항목을 삭제합니다.
3. 남은 항목의 입력값이 원래 줄에 남아 있는지 봅니다.
4. 정렬 기능이 있으면 정렬 뒤에도 같은 항목의 값이 유지되는지 봅니다.

값이 다른 줄로 옮겨 가면 key가 항목 신분증으로 맞지 않거나 배열 state 업데이트가 직접 수정으로 되어 있을 가능성이 큽니다.

AI에게는 key와 배열 업데이트 범위만 좁혀 맡깁니다

아래 프롬프트를 붙이면 AI가 화면 전체를 다시 만들 가능성을 줄일 수 있습니다.

React 목록에서 key warning이 뜨고, 삭제나 정렬 뒤 입력값이 다른 줄로 옮겨 가는 문제가 있습니다.
전체 컴포넌트를 다시 만들지 말고 아래 범위만 확인해 주세요.

1. map() 안에서 반복되는 JSX에 안정적인 key가 있는지 확인
2. key={index}, key={Math.random()}, key={Date.now()}가 있으면 데이터 id 기반으로 교체
3. 항목 생성 때 id가 없다면 생성 시점에 id를 저장하는 최소 수정 제안
4. 삭제, 수정, 정렬에서 배열 state를 직접 바꾸지 않고 새 배열로 업데이트하는지 확인
5. 마지막에 삭제와 정렬 테스트 순서를 알려 주세요

관련 코드:
[map 부분과 todos state 업데이트 부분만 붙여 넣기]

이 프롬프트의 핵심은 key 선택과 배열 업데이트 경로만 보라는 점입니다. AI가 CSS, 레이아웃, 컴포넌트 분리까지 바꾸기 시작하면 원래 문제를 놓치기 쉽습니다.

오늘 고칠 것은 한 줄일 수 있습니다. 다만 그 한 줄은 목록 항목의 신분증입니다. React key warning이 보이면 map() 안의 반복 JSX를 찾고, 데이터에 저장된 안정적인 id를 key로 넣고, 삭제와 정렬 테스트를 합니다. 그 뒤에도 값이 옮겨 가면 배열 state 업데이트가 직접 수정인지 확인합니다.

이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.

참고 출처

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.